# Git 使用教程 — 从零开始配置项目仓库

> 本教程面向从未使用过 Git 的开发新手，手把手带你完成环境配置、项目拉取和日常开发协作。
> 每一步都会解释**为什么要这样做**，让你不仅知道"怎么做"，更理解"为什么"。

---

## 目录

1. [什么是 Git？— 通俗理解](#1-什么是-git--通俗理解)
2. [全局配置：告诉 Git 你是谁](#2-全局配置告诉-git-你是谁)
3. [解决 SSL 证书验证失败问题](#3-解决-ssl-证书验证失败问题)
4. [克隆项目到本地](#4-克隆项目到本地)
5. [在 VSCode 中打开项目](#5-在-vscode-中打开项目)
6. [日常开发工作流](#6-日常开发工作流)
   - 6.1 [创建分支 — 在自己的"工作间"干活](#61-创建分支--在自己的工作间干活)
   - 6.2 [提交到本地仓库 — 给作品"存档"](#62-提交到本地仓库--给作品存档)
   - 6.3 [推送到远程仓库 — 把作品"上交"](#63-推送到远程仓库--把作品上交)
   - 6.4 [拉取远程仓库 — 同步别人的"最新作品"](#64-拉取远程仓库--同步别人的最新作品)
   - 6.5 [合并分支 — 把你的工作成果"合进主线"](#65-合并分支--把你的工作成果合进主线)
7. [VSCode 中的图形化 Git 操作](#7-vscode-中的图形化-git-操作)
8. [常见问题与解决方案](#8-常见问题与解决方案)
9. [Git 命令速查表](#9-git-命令速查表)

---

## 1. 什么是 Git？— 通俗理解

想象你在写一份很重要的报告：

- **没有 Git 的世界**：你每次修改都覆盖原文件，改坏了就回不去了。为了保险，你手动复制备份——`报告_v1.doc`、`报告_v2.doc`、`报告_最终版.doc`、`报告_最终版2.doc`……最后自己都分不清哪个是哪个。
- **有 Git 的世界**：Git 就像一个**超级存档系统**，每次你改完代码，告诉它"存个档"，它就帮你拍一张快照。你可以随时回到任何一个历史存档点，还能看到每次改了什么、谁改的。

**几个核心概念（比喻版）：**

| 概念 | 比喻 | 说明 |
|------|------|------|
| **仓库 (Repository)** | 项目文件夹的"存档箱" | 存放项目所有文件和完整历史记录 |
| **分支 (Branch)** | 平行宇宙 / 独立工作间 | 你可以在自己的工作间随便折腾，不影响别人 |
| **提交 (Commit)** | 存档 / 快照 | 记录"这次我改了什么"，形成一个历史节点 |
| **推送 (Push)** | 上交作业 | 把你本地的存档同步到服务器上 |
| **拉取 (Pull)** | 拿最新资料 | 把服务器上别人的最新改动同步到你本地 |
| **合并 (Merge)** | 汇总工作成果 | 把不同分支的改动合到一起 |

---

## 2. 全局配置：告诉 Git 你是谁

> **为什么？** 每次你提交代码时，Git 会记录"这是谁提交的"。就像你在文件上签名一样，别人一看就知道这个修改是你做的。

打开 **VSCode**，按 `` Ctrl + ` `` （反引号，键盘左上角 Esc 下面）打开终端，依次输入：

### 2.1 配置用户名

```bash
git config --global user.name "你的用户名"
```

各成员对应：

| 姓名 | 用户名 |
|------|--------|
| ly   | `ly`   |
| zb   | `zb`   |
| dw   | `dw`   |
| lyj  | `lyj`  |
| lyq  | `lyq`  |

例如 ly 执行：
```bash
git config --global user.name "ly"
```

### 2.2 配置邮箱

```bash
git config --global user.email "你的邮箱"
```

各成员对应：

| 姓名 | 邮箱 |
|------|------|
| ly   | `ly@szga.com`   |
| zb   | `zb@szga.com`   |
| dw   | `dw@szga.com`   |
| lyj  | `lyj@szga.com`  |
| lyq  | `lyq@szga.com`  |

例如 ly 执行：
```bash
git config --global user.email "ly@szga.com"
```

### 2.3 验证配置是否成功

```bash
git config --global --list
```

你应该能看到类似输出：
```
user.name=ly
user.email=ly@szga.com
```

> 这两行信息说明 Git 已经知道你的身份了，以后每次提交代码都会自动附上你的"签名"。

---

## 3. 关闭 SSL 验证

> ```bash
> git config --global http."https://111.229.199.210/".sslVerify false
> ```
> 这样只有访问我们内部服务器时才跳过验证，其他网址照常检查。

### 3.1 保存凭据（避免每次输入密码）

```bash
git config --global credential.helper store
```

> **为什么？** 默认情况下，每次推送/拉取代码都要输入用户名和密码，非常麻烦。这条命令让 Git 把你的账号密码保存在本地，输入一次以后就不用再输了。就像浏览器"记住密码"功能一样。

---

## 4. 克隆项目到本地

> **为什么？** "克隆"就是把服务器上的整个项目（包括所有文件和完整历史记录）下载到你自己的电脑上。就像把一份完整的项目档案复制到你的办公桌上，你可以在本地随意修改，不会影响服务器上的版本。

### 4.1 选择存放位置

先决定你想把项目放在哪个目录，比如 `D:\projects\`。如果目录不存在，先创建：

```bash
mkdir D:\projects
cd D:\projects
```

### 4.2 执行克隆

```bash
git clone https://111.229.199.210/hunter/under18.git
```

此时会弹出登录窗口或提示输入用户名密码：

- **Username**：输入你的用户名（如 `ly`）
- **Password**：输入你的密码（如 `ly110110`）

> 密码输入时屏幕不会显示任何字符，这是正常的安全设计，直接输完按回车即可。

克隆完成后，你会看到：

```
Cloning into 'under18'...
remote: Enumerating objects: ...
Receiving objects: 100% done
```

### 4.3 进入项目目录

```bash
cd under18
```

> 至此，项目已经完整下载到你的电脑了！你可以用 `dir` 命令看看项目里有什么文件。

---

## 5. 在 VSCode 中打开项目

1. 打开 VSCode
2. 点击菜单 **文件 → 打开文件夹**
3. 选择刚才克隆下来的 `under18` 文件夹（如 `D:\projects\under18`）
4. 点击 **选择文件夹**

> **为什么打开文件夹而不是单个文件？** VSCode 以文件夹为单位管理项目，打开整个文件夹后，左侧资源管理器会显示完整的项目结构，Git 功能也会自动生效。

打开后，点击左侧活动栏的 **源代码管理** 图标（看起来像分支的图标，或按 `Ctrl+Shift+G`），你应该能看到 Git 已经识别到这个仓库了。

---

## 6. 日常开发工作流

> 日常开发的基本节奏就是：**建分支 → 写代码 → 提交 → 推送**，就像：开自己的工作间 → 干活 → 存档 → 上交。

### 6.1 创建分支 — 在自己的"工作间"干活

> **为什么需要分支？** 想象 `main` 分支是项目的"主展厅"，展示的是当前最稳定的版本。如果大家都直接在主展厅里施工，互相干扰不说，还可能把展厅搞塌。所以每人开一个"独立工作间"（分支），在自己的工作间里随便折腾，搞好了再把成果搬到主展厅。

#### 查看当前在哪个分支

```bash
git branch
```

输出中带 `*` 的是你当前所在的分支：
```
* main
```

#### 创建并切换到新分支

```bash
git checkout -b 你的分支名
```

**分支命名建议**：用 `功能/描述` 或 `修复/描述` 的格式，例如：
```bash
git checkout -b feature/login-page    # 开发登录页面功能
git checkout -b fix/header-bug        # 修复头部bug
git checkout -b feature/user-manage   # 开发用户管理功能
```

> **比喻**：`checkout -b` 就像在说"给我开一间叫 xxx 的新工作间，我要进去了"。从此你的所有修改都在这个独立空间里，不会动到主展厅。

#### 切换回已有分支

```bash
git checkout main          # 切回主分支
git checkout feature/login # 切回你的功能分支
```

> **注意**：切换分支前，确保当前分支的改动已经提交（存档），否则 Git 可能会阻止你切换，或者把未提交的改动带到另一个分支。

---

### 6.2 提交到本地仓库 — 给作品"存档"

> **为什么？** 提交（Commit）就像游戏里的"存档"。你写了一段代码，觉得可以了，就存个档。如果后面改坏了，可以随时回到这个存档点。**不存档的改动，关机就没了！**

#### 第一步：查看你改了什么

```bash
git status
```

你会看到哪些文件被修改了、新增了、删除了。红色表示还没加入暂存区，绿色表示已加入暂存区。

> **什么是暂存区？** 提交分两步：先把要提交的文件放进"暂存区"（像购物车），再统一"结账"（提交）。这样可以让你精确控制哪些改动要提交，哪些暂时不提交。

#### 第二步：添加到暂存区

添加所有改动：
```bash
git add .
```

或者只添加某个文件：
```bash
git add backend/app/core/config.py
```

> `git add .` 中的 `.` 代表当前目录下所有改动，这是最常用的方式。就像把购物车里塞满你要买的东西。

#### 第三步：提交

```bash
git commit -m "简要描述你做了什么"
```

例如：
```bash
git commit -m "feat: 添加用户列表页面"
git commit -m "fix: 修复登录页面样式问题"
git commit -m "docs: 更新README文档"
```

**提交信息规范**（建议但不强制）：

| 前缀 | 含义 | 示例 |
|------|------|------|
| `feat:` | 新功能 | `feat: 添加导出功能` |
| `fix:` | 修复bug | `fix: 修复分页错误` |
| `docs:` | 文档修改 | `docs: 更新API文档` |
| `style:` | 样式调整 | `style: 调整按钮间距` |
| `refactor:` | 重构 | `refactor: 优化查询逻辑` |

> **比喻**：`commit` 就是在说"把这些改动存个档，备注写 xxx"。以后随时可以翻看这个存档记录。

---

### 6.3 推送到远程仓库 — 把作品"上交"

> **为什么？** 提交只是存在你本地电脑上，别人看不到。推送（Push）就是把你的存档同步到服务器，这样团队成员就能看到你的最新代码了。就像你写完作业要"上交"一样，不交老师看不到。

```bash
git push origin 你的分支名
```

例如：
```bash
git push origin feature/login-page
```

**第一次推送新分支时**，需要加 `-u` 参数建立追踪关系：
```bash
git push -u origin feature/login-page
```

> 加了 `-u` 后，以后在这个分支上只需要 `git push` 就行了，不用再写完整的命令。就像第一次去快递站要登记地址，以后直接报手机号就行。

---

### 6.4 拉取远程仓库 — 同步别人的"最新作品"

> **为什么？** 其他人也在写代码并推送到服务器。如果别人更新了 `main` 分支，你本地的 `main` 还是旧的，就需要"拉取"来同步。就像你的文件夹是昨天的版本，需要去档案室拿最新版来更新。

#### 方式一：pull（拉取并合并，推荐新手使用）

```bash
git checkout main            # 先切到 main 分支
git pull origin main         # 拉取远程 main 的最新代码
```

#### 方式二：定期同步到你自己的功能分支

当你开发到一半，想同步 main 分支的最新改动到你的功能分支：

```bash
git checkout feature/login-page   # 切到你的功能分支
git pull origin main              # 把 main 的最新改动拉下来并合并
```

> **注意**：拉取前确保你当前分支的改动已经提交，否则可能产生冲突。

---

### 6.5 合并分支 — 把你的工作成果"合进主线"

> **为什么？** 你在功能分支上开发完了，需要把成果合并到 main 分支，这样大家才能看到你的新功能。就像你在自己的工作间做完了产品，要搬到主展厅展示。

#### 步骤

```bash
git checkout main              # 1. 先切到 main 分支
git pull origin main           # 2. 先拉取最新的 main（确保是最新的）
git merge feature/login-page   # 3. 把你的功能分支合并进来
git push origin main           # 4. 推送到远程服务器
```

> **合并冲突怎么办？** 如果两个人改了同一个文件的同一行，Git 不知道该听谁的，就会报"冲突"。此时需要手动打开冲突文件，选择保留哪个版本，然后重新 `add → commit → push`。冲突文件里会有这样的标记：
> ```
> <<<<<<< HEAD
> 你当前分支的代码
> =======
> 对方分支的代码
> >>>>>>> feature/login-page
> ```
> 删掉不需要的部分和标记符号，保留正确的代码即可。

#### 合并完成后删除功能分支（可选）

```bash
git branch -d feature/login-page   # 删除本地分支
```

> 就像工作间用完了可以拆掉，保持工作区整洁。

---

## 7. VSCode 中的图形化 Git 操作

> 不习惯命令行？VSCode 提供了图形化界面，鼠标点点就能完成大部分操作。

### 7.1 源代码管理面板

按 `Ctrl+Shift+G` 打开源代码管理面板：

- **修改的文件**：点击文件名可以查看具体改了什么（绿色=新增，红色=删除，蓝色=修改）
- **暂存**：点击文件旁边的 `+` 号 = `git add`
- **取消暂存**：点击已暂存文件旁边的 `-` 号 = `git reset HEAD`
- **提交**：在上方输入框写提交信息，点击 ✓ 按钮 = `git commit -m "..."`
- **撤销修改**：点击文件旁边的 ↩ 按钮 = 丢弃未暂存的改动（**慎用，改了就回不去了！**）

### 7.2 分支操作

点击 VSCode 左下角的 **分支名**（如 `main`），可以：

- **创建新分支** → 选择"创建新分支" → 输入分支名
- **切换分支** → 从列表中选择要切换的分支
- **删除分支** → 选择要删除的分支

### 7.3 推送和拉取

- **推送**：点击源代码管理面板上方的 `...` → 推送，或点击左下角分支名旁边的 ↕ 同步按钮
- **拉取**：点击 `...` → 拉取

---

## 8. 常见问题与解决方案

### Q1：`SSL certificate problem: self signed certificate`

```
fatal: unable to access '...': SSL certificate problem: self signed certificate
```

**原因**：自签名证书不被信任。

**解决**：
```bash
git config --global http.sslVerify false
```
或只针对我们的服务器：
```bash
git config --global http."https://111.229.199.210/".sslVerify false
```

### Q2：每次 push/pull 都要输入密码

**解决**：
```bash
git config --global credential.helper store
```
然后再推送一次，输入密码后就会被记住。

### Q3：`fatal: not a git repository`

**原因**：你不在 Git 仓库目录中。

**解决**：先 `cd` 到项目目录（包含 `.git` 文件夹的目录）再执行 Git 命令。

### Q4：`error: failed to push some refs`

```
! [rejected] main -> main (fetch first)
```

**原因**：远程有别人推送的新代码，你本地不是最新的。

**解决**：先拉取再推送：
```bash
git pull origin main
git push origin main
```

### Q5：提交错了想撤回

只撤回上一次提交（代码改动保留）：
```bash
git reset --soft HEAD~1
```

丢弃上一次提交和改动（**危险！改了就没了**）：
```bash
git reset --hard HEAD~1
```

### Q6：合并冲突了怎么办

1. 打开冲突文件，看到 `<<<<<<<`、`=======`、`>>>>>>>` 标记
2. 手动选择保留哪段代码，删除标记符号
3. 保存文件后：
```bash
git add .
git commit -m "fix: 解决合并冲突"
```

---

## 9. Git 命令速查表

| 操作 | 命令 | 说明 |
|------|------|------|
| 克隆项目 | `git clone 地址` | 首次下载项目 |
| 查看状态 | `git status` | 看哪些文件改了 |
| 添加到暂存区 | `git add .` | 把所有改动加入暂存区 |
| 提交 | `git commit -m "描述"` | 存档并写备注 |
| 推送 | `git push origin 分支名` | 上传到服务器 |
| 拉取 | `git pull origin 分支名` | 下载服务器最新代码 |
| 创建+切换分支 | `git checkout -b 分支名` | 开新工作间 |
| 切换分支 | `git checkout 分支名` | 换工作间 |
| 合并分支 | `git merge 分支名` | 把指定分支合并到当前分支 |
| 查看分支列表 | `git branch` | 看有哪些工作间 |
| 删除分支 | `git branch -d 分支名` | 拆掉工作间 |
| 查看提交历史 | `git log --oneline` | 查看存档记录 |
| 撤销未暂存的修改 | `git checkout -- 文件名` | 恢复到上次提交的状态 |

---

> **最后提醒**：
> - **勤提交**：写完一个功能点就提交一次，别攒一大堆再提交，方便出问题时回溯
> - **写清楚提交信息**：别写"update"或"fix"，要写具体改了什么，比如"fix: 修复用户列表搜索无响应问题"
> - **推送前先拉取**：推送 main 分支前先 `git pull`，避免冲突
> - **有疑问随时问**：Git 操作失误可以恢复（几乎所有操作都可以撤销），不用害怕
