git完整版本

# 1.Git是什么

**Git (分布式版本控制工具):**

– 它是一个**软件工具**,安装在本地计算机上。
– 它的作用是**追踪**和**管理**项目(尤其是代码)的**历史版本**。
– “分布式”意味着每个开发者都有完整的代码历史记录,无需依赖中心服务器即可工作。

**GitHub (代码托管平台):**

– 它是一个**基于网络的在线服务/平台**。
– 它的作用是**托管**(存储)使用 Git 进行版本控制的代码仓库。
– 它提供了一个协作环境,方便团队成员分享代码、合并更改、进行代码审查等。

# 2.Git的用途

Git 作为版本控制工具,主要用于管理项目开发的历史记录和协作,其主要用途包括:

1. **追踪历史记录 (Tracking History):**
– 它可以记录项目中**每一次文件更改**的详细信息(谁在什么时候做了什么修改)。
– 你可以随时**查看、比较**项目在不同时间点的状态,相当于拥有了“时间机器”。
2. **版本回退 (Reverting Versions):**
– 如果代码出现 bug 或需要撤销最近的更改,Git 可以轻松地将整个项目**恢复到历史上的任何一个工作版本**。
3. **分支管理 (Branch Management):**
– Git 最强大的功能之一是**分支 (Branch)**。它允许开发者在不影响主线代码的情况下,创建独立的环境来开发新功能或修复 bug。
– 完成后,可以将这些分支**合并 (Merge)** 回主线。
4. **多人协作 (Team Collaboration):**
– 通过与 GitHub、GitLab 或 Bitbucket 等**代码托管平台**配合使用,Git 使得团队成员能够**同时**在同一个项目上工作,并有序地整合彼此的修改,避免冲突。
5. **代码备份与同步 (Code Backup and Synchronization):**
– 将本地仓库同步到远程仓库(如 GitHub),可以作为代码的**远程备份**,防止本地数据丢失。
– 这也方便了在多台设备之间**同步**你的工作进度。

**总而言之,Git 的核心作用就是**确保代码的演变过程是**安全、可控、可追溯**的,并有效地支持**团队协作**。

# 3.为什么使用GIT

使用 Git 的主要原因在于它能够解决在软件开发(或任何文档项目管理)过程中遇到的**历史管理、错误回退和团队协作**等核心问题。

### 1. 💾 确保项目历史的安全性与完整性 (Security and Integrity)

– **完整的历史记录:** Git 会记录项目自创建以来的每一次有效更改(**Commit**),包括修改的内容、修改人和修改时间。这就像项目有一个**完整的审计追踪**,任何时候都可以知道发生了什么。
– **版本回溯(后悔药):** 如果你发现最新的代码引入了 Bug,或者想要撤销一系列操作,Git 可以让你**一键回到历史上的任何一个稳定版本**,极大地降低了犯错的风险。 *

### 2. 🤝 强大的团队协作能力 (Team Collaboration)

– **高效合并:** 多个开发者可以**同时**在项目的不同部分工作。当他们完成自己的工作后,Git 可以智能地**合并**这些修改,减少人工协调和文件覆盖的风险。
– **分支隔离 (Branching):** 这是 Git 最重要的特性。开发者可以在一个**独立的分支**上开发新功能(Feature)、修复 Bug(Fix)或进行实验,而不会影响到项目主线(**Main/Master**)的稳定性。只有在测试通过后,才将分支合并回去。 *

### 3. 🌐 分布式优势 (Distributed Advantage)

– **本地完整备份:** 由于 Git 是一个“分布式”系统,每个克隆了代码仓库的开发者本地都拥有**完整的项目历史副本**。这意味着即使中心服务器(如 GitHub)出现故障,团队成员仍然可以在本地继续工作,并在服务器恢复后轻松同步。
– **离线工作:** 开发者可以在没有网络连接的情况下,进行提交 (Commit)、创建分支等所有的本地版本控制操作。

### 4. 🚀 标准化流程 (Standardized Workflow)

– **专业标准:** Git 和 GitHub/GitLab 等平台已成为现代软件开发的**行业标准**。掌握它们是软件工程师、数据科学家等技术职位的基本技能。
– **清晰的工作流程:** 它提供了一套清晰、一致的**工作流程(Git Flow)**,帮助团队规范代码的提交、审查和发布过程。

简而言之:**使用 Git 可以让您的项目管理变得更专业、更安全、更高效。**

# 4.要学什么?怎么用

## 4.1基本概念

### 4.1.1仓库

Git 仓库(Repository,简称 Repo)是 Git 用来保存项目及其历史记录的地方。你可以把它想象成一个**“带有时间机器的项目文件夹”**。

在 Git 仓库中,不仅保存了你的代码文件,还保存了每一次修改的历史(Commit)、分支(Branch)以及标签(Tag)。

以下是关于 Git 仓库的核心概念、结构以及如何操作的完整指南。

——

#### 1. Git 仓库的两种形式

Git 是分布式的,这意味着仓库可以在不同的地方存在。

– 本地仓库 (Local Repository):

位于你自己的电脑上。包含了项目的所有历史记录。即使没有网络,你也可以提交代码、查看历史或切换分支。

– 远程仓库 (Remote Repository):

托管在服务器上(如 GitHub, GitLab, Gitee)。用于团队协作和代码备份。

——

#### 2. 如何获取一个仓库

主要有两种方式来“拥有”一个 Git 仓库:

##### A. 将现有文件夹初始化为仓库 (`git init`)

如果你有一个现成的项目文件夹,想开始用 Git 管理它:

“`Bash
cd your_project_folder # 进入你的项目目录
git init # 初始化
“`

*这会在当前目录下创建一个隐藏的 `.git` 文件夹,Git 的所有魔法都在这里发生。*

##### B. 克隆远程仓库 (`git clone`)

如果你想下载别人的代码或自己托管在 GitHub 上的代码:

“`Bash
git clone https://github.com/username/project.git
“`

*这会下载整个项目及其完整的历史记录到你的电脑上。*

——

#### 3. 仓库内部的工作流 (核心概念)

在 Git 仓库中工作时,文件会流经三个主要区域。理解这一点是使用 Git 的关键:

1. **工作区 (Working Directory):** 你平时编辑代码、肉眼看得到的文件夹。
2. **暂存区 (Staging Area / Index):** 一个临时的保存区域,你把你想要提交的文件“挑选”出来放在这里。
3. **本地仓库 (Local Repository):** 实际上存储历史快照的地方。

**基本操作流程:**

1. **修改**文件(在工作区)。
2. **`git add`** 将文件放入暂存区。
3. **`git commit`** 将暂存区的内容永久保存到本地仓库。

——

#### 4. 常用仓库管理命令

| **操作** | **命令** | **说明** |
| ————– | —————————– | ——————————————————– |
| **查看状态** | `git status` | **最重要命令**。随时查看哪些文件被修改了,哪些在暂存区。 |
| **添加文件** | `git add .` | 将当前目录下所有修改添加到暂存区。 |
| **提交保存** | `git commit -m “描述”` | 将暂存区内容生成一个新版本(快照)。 |
| **查看历史** | `git log` | 查看提交历史记录。 |
| **关联远程** | `git remote add origin ` | 将本地仓库连接到远程服务器。 |
| **推送到远程** | `git push -u origin main` | 将本地的提交上传到远程仓库。 |
| **拉取更新** | `git pull` | 从远程仓库下载最新的更改并合并到本地。 |

——

#### 5. 两个重要的配置文件

在仓库根目录下,有两个文件非常重要:

– **`.gitignore`**:
– 这是一个文本文件,列出了 Git **应该忽略**的文件。
– **用途:** 防止编译产生的临时文件(如 `.o`, `.exe`, `build/`)、敏感信息(如密码配置)或系统文件(如 `.DS_Store`)被提交到仓库中。
– **`README.md`**:
– 这是项目的说明书。通常使用 Markdown 格式编写。
– GitHub/Gitee 会默认在项目主页展示这个文件的内容。

——

#### 6. 常见误区提示

> 注意: 不要手动修改或删除项目根目录下的 .git 隐藏文件夹。
>
> 如果删除了它,你的项目文件夹就会变回普通文件夹,所有的版本历史记录、分支信息都会永久丢失。

### 4.1.2 协议

——

#### 1. 本地协议 (Local Protocol)

这是最基本的协议,用于在同一台机器上不同目录之间,或通过共享文件系统(如 NFS)进行克隆。

– **格式:**
– `git clone /opt/git/project.git`
– `git clone file:///opt/git/project.git` (显式指定)
– **优点:**
– **简单:** 不需要配置服务器,利用现有的文件权限。
– **快速:** 如果在同一文件系统下,Git 会尝试使用硬链接(Hard Links),速度极快。
– **缺点:**
– **局限性:** 无法跨网段访问(除非挂载了共享网络硬盘)。
– **安全性:** 如果使用共享文件系统,通常意味着用户有对整个仓库目录的完整 shell 访问权限,难以做到精细的权限控制。

#### 2. HTTP / HTTPS 协议

这是目前最流行的协议,尤其是 **HTTPS**。现代 Git 使用的是 “Smart HTTP” 协议,而在早期版本中使用的是效率较低的 “Dumb HTTP”。

– **格式:** `https://github.com/user/project.git`
– **优点:**
– **防火墙友好:** 使用标准的 80 或 443 端口,几乎所有企业防火墙都允许通过。
– **简便性:** 不需要配置 SSH 密钥,只需要用户名/密码(或 Token)。
– **单一 URL:** 在现代 Git 服务器(如 GitHub/GitLab)上,匿名只读访问和认证写访问通常可以使用同一个 URL。
– **缺点:**
– **凭证管理:** 每次推送都需要输入密码(除非配置了凭证助手 Credential Helper)。
– **性能:** 虽然 Smart HTTP 已经很快,但在某些极端的大文件传输场景下,可能略慢于 SSH。

#### 3. SSH 协议 (Secure Shell)

这是在 Linux/Unix 环境下进行自主托管(Self-hosted)或团队开发最常用的协议。

– **格式:** `user@server:project.git` 或 `ssh://user@server/project.git`
– **优点:**
– **安全性高:** 数据全程加密,且必须经过身份验证。
– **无需输入密码:** 配置 SSH Key 后,推送代码非常流畅,无需人工干预。
– **原生支持:** 几乎所有 Linux 服务器都默认安装并开启了 SSH 服务。
– **缺点:**
– **不支持匿名访问:** 必须有服务器的访问权限才能读取数据(这对开源项目是不利的)。
– **配置门槛:** 对于新手来说,生成和管理 SSH 密钥对(public/private key)可能稍显复杂。

#### 4. Git 协议

这是 Git 自带的一种守护进程协议(daemon),监听 9418 端口。

– **格式:** `git://server/project.git`
– **优点:**
– **速度最快:** 它是专门为 Git 传输设计的,且没有加密解密的开销。
– **缺点:**
– **无身份验证:** 这是一个**纯粹的传输协议**,通常只用于公开项目的只读访问(Read-only)。
– **防火墙问题:** 使用非标准的 9418 端口,容易被企业防火墙拦截。
– **无加密:** 数据传输是明文的,不适合传输敏感代码。

——

#### 总结与对比

| **协议类型** | **典型用途** | **优点** | **缺点** |
| ———— | ————————– | ————————– | ———————— |
| **Local** | 本地备份、NFS 共享 | 极快、配置简单 | 仅限本地或共享磁盘 |
| **HTTPS** | GitHub/GitLab 通用 | 穿透防火墙、通用性强 | 推送时需凭证管理 |
| **SSH** | 团队内部开发、Linux 服务器 | 安全、免密推送 (Key)、高效 | 不支持匿名读取 |
| **Git** | 公共开源项目的只读镜像 | 传输速度最快 | 无加密、无鉴权、非标端口 |

### 4.1.3配置用户名和邮箱

#### 1. 全局配置(最常用)

如果你希望这台电脑上所有的项目都默认使用同一个身份(比如你的 GitHub 账号),使用 `–global` 参数。

“`Bash
git config –global user.name “你的名字”
git config –global user.email “你的邮箱@example.com”
“`

– **你的名字**:可以用英文也可以用中文,这里建议使用你常用的 ID (如 GitHub 用户名)。
– **你的邮箱**:建议使用你注册 GitHub/Gitee/GitLab 时用的邮箱。这样你的提交记录才能在这些网站上正确统计(也就是会有“绿色的格子”)。

——

#### 2. 针对特定项目配置(局部)

如果你只是想在**当前这个特定项目**中使用不同的身份(例如:平时用个人邮箱,但这个项目是学校作业或公司项目,需要用特定邮箱),你需要先进入该项目的文件夹,然后去掉 `–global` 参数:

“`Bash
cd 你的项目目录
git config user.name “你的特定名字”
git config user.email “你的特定邮箱@university.edu.cn”
“`

*注意:局部配置的优先级高于全局配置。*

——

#### 3. 如何查看配置是否成功

你可以使用以下命令查看当前生效的配置列表:

“`Bash
git config –list
“`

或者只查看特定的项:

“`Bash
git config user.name
git config user.email
“`

### 4.1.4. 四个“物理”区域 (代码存放在哪里?)

这四个概念按顺序构成了代码的“流转路径”:

– **本地工作区 (Working Directory)**
– **是什么:** 就是你电脑文件管理器里能看得到的那个文件夹。
– **状态:** 你在这里写代码、改论文。这里的修改是**未被追踪**的,如果不保存到 Git,删了就找不回了。
– *对应的动作:编辑文件。*
– **暂存区 (Staging Area / Index)**
– **是什么:** 一个临时的“购物车”或“发货清单”。
– **作用:** Git 允许你挑选文件提交。比如你改了 A 和 B 两个文件,但只想先把 A 存入历史记录,你就只把 A 放到暂存区。
– *对应的命令:* `git add`
– **本地仓库 (Local Repository)**
– **是什么:** 位于你电脑上的 `.git` 文件夹内部。
– **作用:** 存档的地方。一旦提交到这里,就生成了一个永久的历史版本(快照)。
– *对应的命令:* `git commit`
– **远程仓库 (Remote Repository)**
– **是什么:** 托管在互联网上的服务器(如 GitHub, Gitee, GitLab)。
– **作用:** 类似于网盘,用于备份代码和与他人协作。
– *对应的命令:* `git push` (上传) / `git pull` (下载)

——

### 4.1.5. 两个“逻辑”标记 (如何定位代码?)

这两个概念用于在海量的历史记录中找到你想要的那一刻:

– **版本号 (Commit ID / Hash)**
– **是什么:** Git 不像 Word 那样用 `v1`, `v2` 命名,而是给每一次提交生成一个**唯一的、长长的字符串**(哈希值),例如 `a1b2c3d…`。
– **作用:** 它是版本的“身份证号”。如果你想回退到某次修改,就需要用到这个号码。
– **HEAD**
– **是什么:** 一个**指针**,或者理解为地图上的“你在这里” (You are here) 标记。
– **作用:** 它指向你当前正在操作的那个版本(通常是当前分支的最新一次提交)。当你切换分支或回退版本时,HEAD 就会移动,你的工作区文件也会随之改变。

——

### 总结:一张图看懂数据流向

根据你图片中的层级,标准的工作流是这样的:

“`mermaid
graph LR
A[本地工作区] — git add –> B[暂存区]
B — git commit –> C[本地仓库]
C — git push –> D[远程仓库]
“`

1. 在 **工作区** 写代码。
2. 用 `git add` 放入 **暂存区**。
3. 用 `git commit` 生成 **版本号** 并存入 **本地仓库**(HEAD 指向这里)。
4. 用 `git push` 同步到 **远程仓库**。

## 4.2操作

### 4.2.1基本操作

#### 1. 代码流转三部曲 (Add -> Commit -> Push)

这三个命令对应了代码从你电脑走向远程服务器的三个阶段(对应图2的层级):

##### **Step 1: 暂存 (`git add`)**

– **图解位置:** 本地工作区 $\rightarrow$ 暂存区
– **作用:** 挑选你想要提交的文件。
– **操作:**
– `git add .`:把所有修改过的文件(比如你刚写完的 `.cpp` 和 `.h` 头文件)全部放入暂存区。
– `git add main.cpp`:只暂存特定文件。

##### **Step 2: 提交 (`git commit`)**

– **图解位置:** 暂存区 $\rightarrow$ 本地仓库
– **图中批注解读:** **“区分不同类别的修改”**。
– 这意味着你的 commit message(提交信息)应该清晰地分类。比如,不要把“修复 Bug”和“开发新功能”混在一个 commit 里提交。
– **良好的习惯:** 每次只做一个逻辑上的修改就 commit 一次。
– **命令:** `git commit -m “Fix: 修复了内存泄漏问题”`

##### **Step 3: 推送 (`git push`)**

– **图解位置:** 本地仓库 $\rightarrow$ 远程仓库
– **作用:** 把你的代码同步到 GitHub/Gitee 服务器。
– **命令:** `git push origin main`

——

#### 2. 同步更新:Fetch vs Pull (图1的重点)

你的思维导图中非常准确地把 `git pull` 拆解成了两步,这是很多初学者容易搞混的地方。

##### **拉取 (`git fetch`)**

– **图中批注解读:** **“将远程仓库所包含分支的最新 commit-id 记录到本地文件”**。
– 这是一个非常底层的解释。它的意思是:`fetch` 只是去远程服务器“看了一眼”,把远程最新的变化(Commit ID)下载到了本地的 `.git` 目录里(更新了 `origin/main` 指针),但**并没有**修改你工作区里的代码。
– **此时的状态:** 你的代码还没变,但 Git 已经知道远程有了新版本。

##### **拉取合并 (`git pull`)**

– **图解公式:** `git pull` = `git fetch` + `git merge`
– **作用:** 不仅下载远程的更新(Fetch),还自动把这些更新合并(Merge)到你当前正在编辑的文件里。
– **建议:** 在绝大多数日常开发中,直接用 `git pull` 即可。但如果你担心远程代码和你的有冲突,可以先 `fetch` 看看,再决定要不要 `merge`。

——

#### 3. 监控与“后悔药” (Status, Log, Reflog)

##### **查看状态 (`git status`)**

– **作用:** 这是一个仪表盘。它告诉你文件当前在哪个区域(是已修改但未暂存?还是已暂存未提交?)。

##### **查看历史 (`git log`)**

– **作用:** 查看提交日志(Commit ID, 作者, 时间, 内容)。

##### **救命命令 (`git reflog`)**

– **这是图中最高阶的命令。**
– **区别:** `git log` 记录的是**代码的提交历史**;`git reflog` 记录的是**你的每一次 Git 操作历史**(包括被你撤销的、删除的 commit)。
– **场景:** 比如你不小心 `git reset –hard` 把昨晚写的代码回退没了,`git log` 里已经看不到那条记录了,但在 `git reflog` 里还能找到!它是 Git 的“黑匣子”,能帮你找回丢失的代码。

### 4.2.2逆向操作

#### 1. 工作区 (Workspace) —— 还没 `git add`

当你修改了文件,但发现改错了,想**放弃修改**,恢复到上一次提交的状态:

– **推荐指令 (新版):**

“`Bash
git restore <文件名>
# 或者放弃所有修改
git restore .
“`

– **传统指令 (旧版):**

“`Bash
git checkout — <文件名>
“`

——

#### 2. 暂存区 (Staging Area) —— 已经 `git add`,但还没 `git commit`

当你把文件放入了暂存区,但想**撤回**(变回未暂存状态,但保留修改内容):

– **推荐指令 (新版):**

“`Bash
git restore –staged <文件名>
“`

– **传统指令 (旧版):**

“`Bash
git reset HEAD <文件名>
“`

——

#### 3. 本地仓库 (Local Repository) —— 已经 `git commit`

当你已经提交了代码,但想撤销这次提交。这里有三种程度的”后悔药”:

##### A. 只是提交信息写错了,或者漏提了几个文件

不需要删除提交,直接**修正**最后一次提交:

“`Bash
# 修改后重新提交,会覆盖上一次的 commit ID
git commit –amend
“`

##### B. 彻底撤销提交 (Git Reset)

使用 `git reset` 可以将当前分支的指针(HEAD)向后移动。

– **场景 1:撤销提交,但保留代码在暂存区** (Soft Reset)

– *适用于:想重新调整一下提交内容再 commit。*

“`Bash
git reset –soft HEAD~1
“`

– **场景 2:撤销提交,保留代码在工作区** (Mixed Reset, 默认)

– *适用于:发现代码还有问题,想继续改改。*

“`Bash
git reset HEAD~1
“`

– **场景 3:彻底放弃修改,回到上一个版本** (Hard Reset) ⚠️ **危险操作**

– *适用于:刚才写的全是垃圾,完全不想要了。*

“`Bash
git reset –hard HEAD~1
“`

——

#### 4. 远程仓库 (Remote Repository) —— 已经 `git push`

代码已经推送到远程服务器(如 GitHub/GitLab),此时要非常小心,因为其他人可能已经拉取了你的代码。

##### A. 安全做法:使用 `git revert` (推荐)

这不会删除历史记录,而是生成一个新的提交,**反向**抵消掉之前的修改。

– *适用于:公共分支(如 master/main/develop),不破坏他人协作。*

“`Bash
git revert
git push origin <分支名>
“`

##### B. 暴力做法:强制推送 (Force Push)

如果你确定只有你一个人在使用这个分支,或者你必须抹除某次提交记录(如提交了密码):

1. 先在本地回滚(如 `git reset –hard`)。

2. 强制推送到远程:

“`Bash
git push –force
# 或者更安全的做法(如果远程有更新则报错)
git push –force-with-lease
“`

——

#### 5. 救命药:Git Reflog

如果你不小心用 `git reset –hard` 删除了重要的提交,或者误删了分支,Git 还有一个隐藏的”后悔药”。

Git 会记录HEAD引用的每一次移动(即使是 reset 掉的)。

1. **查看记录:**

“`Bash
git reflog
“`

你会看到类似 `HEAD@{1}: reset: moving to HEAD~1` 的记录。

2. 找回丢失的提交:

找到你丢失的那个 Commit ID,然后重置回去:

“`Bash
git reset –hard
“`

#### 6.checkout

##### 1. `git checkout — file`

– **作用:** 撤销**单个文件**在**工作区**中的修改。
– **效果:** 用当前 HEAD 版本的 `file` 文件内容**覆盖**工作区和暂存区的同名文件。
– **新命令推荐:** `git restore ` (作用更明确)

##### 2. `git checkout` (无参数或仅带分支名)

当 `git checkout ` 时,Git 会:

1. 切换到指定分支。
2. 将**整个工作区**的内容更新为该分支最新提交(HEAD)的状态。
3. 如果切换分支会导致**未提交**的修改丢失,`git checkout` **会失败**并提示你先提交或藏匿(stash)修改。

– **如果没有任何修改:** 只是简单切换分支。
– **如果工作区有修改:** 通常不会导致 `workspace -> null` 的效果,因为它会尝试保护你的修改。

##### 3. `git checkout -f` (或 `git checkout –force`) ⚠️ 危险操作

这是最直接实现 “workspace -> null” 的方式,但通常用于**切换分支**时。

– **作用:** **强制**切换到指定的分支或提交。
– **效果:**
– 它会**丢弃**工作区和暂存区中**所有**与目标分支/提交冲突的**未提交**修改。
– 这正是您图片中 “workspace -> null” 最**暴力**的实现方式:它会强制清除工作区中那些妨碍切换分支的修改。
– **新命令推荐:** 如果你的目的是放弃工作区修改,请使用 `git restore .` 或 `git reset –hard`,而不是依赖 `checkout -f` 的副作用。

——

##### 💡 总结与更推荐的 Git 逆向操作

为了避免混淆,建议使用更现代、目标更明确的命令来清除工作区修改:

| **目标** | **老命令(git checkout 系列)** | **新命令(推荐)** |
| ——————————————- | ——————————- | ———————– |
| **撤销单个文件修改** | `git checkout — ` | `git restore ` |
| **撤销所有文件修改** | 不直接推荐 | `git restore .` |
| **彻底回退到上个版本** (放弃所有修改和暂存) | 不直接推荐 | `git reset –hard HEAD` |

#### 总结速查表

| **场景** | **推荐指令** | **作用** |
| ————————- | ————————- | —————————— |
| **工作区** (改乱了想还原) | `git restore .` | 丢弃本地所有未暂存的修改 |
| **暂存区** (add 后想撤回) | `git restore –staged .` | 将文件从暂存区移回工作区 |
| **修补提交** (写错注释) | `git commit –amend` | 修改最后一次提交而不产生新记录 |
| **撤销提交** (想重新提) | `git reset –soft HEAD~1` | 撤销 Commit,保留文件在暂存区 |
| **完全回退** (不要代码了) | `git reset –hard HEAD~1` | 彻底丢弃最后一次提交的所有内容 |
| **远程回退** (安全做法) | `git revert ` | 新增一个反向提交来抵消修改 |

### 4.2.3 本地仓库整理操作

##### 1. 清理分支 (Branch Cleanup)

随着开发进行,本地会积累大量已经合并或废弃的分支。

– **查看本地分支:**

“`Bash
git branch
“`

– 删除已合并的分支(安全删除):

Git 会检查该分支是否已合并到当前分支,如果未合并会阻止删除。

“`Bash
git branch -d <分支名>
“`

– 强制删除分支(慎用):

不管是否合并,直接删除(适用于废弃的实验性分支)。

“`Bash
git branch -D <分支名>
“`

– 清理无效的远程追踪分支:

如果远程仓库(如 GitHub/GitLab)上的分支已经被删除,但你本地的 git branch -a 还能看到 remotes/origin/xxx,使用此命令清理:

“`Bash
git fetch -p
# 或者
git remote prune origin
“`

> 💡 高级技巧:批量删除已合并分支
>
> 如果你有大量已合并的分支(master/main 除外),可以在 Bash 中运行:
>
> git branch –merged | grep -v “\*” | grep -v “master” | grep -v “main” | xargs -n 1 git branch -d

——

##### 2. 清理工作区 (Working Directory Cleanup)

当你编译项目或生成了大量临时文件(且没有加入 `.gitignore`)时,可以使用 `git clean`。

– 第一步:演习(Dry Run)—— 非常重要!

先看看如果不加干预会删除哪些文件,防止误删重要数据。

“`Bash
git clean -n
# 如果想连同文件夹一起看:
git clean -nd
“`

– 第二步:执行清理

确认无误后,执行删除。

“`Bash
# 删除未追踪的文件
git clean -f
# 删除未追踪的文件和目录
git clean -fd
“`

——

##### 3. 清理暂存区 (Stash Cleanup)

开发过程中可能使用 `git stash` 临时保存过代码,久而久之会堆积。

– **查看暂存列表:**

“`Bash
git stash list
“`

– **删除指定的暂存:**

“`Bash
git stash drop stash@{0} # 删除索引为0的暂存
“`

– 清空所有暂存(慎用):

一次性删除所有 stash 记录,无法恢复。

“`Bash
git stash clear
“`

——

##### 4. 整理提交历史 (Commit History)

如果你的提交历史很乱(例如有很多 “fix typo”, “update”, “wip” 等琐碎提交),可以使用变基(Rebase)将其合并。

– 交互式变基:

整理最近的 N 次提交(例如最近 3 次)。

“`Bash
git rebase -i HEAD~3
“`

– 进入编辑器后,将需要合并的提交前的 `pick` 改为 `squash` (或 `s`)。
– 保存退出后,Git 会让你编辑合并后的新 Commit Message。

##### ⚠️ 警告:什么时候绝对不要用 Rebase?

**如果这几个提交是在公共分支(如 `master` / `main` / `develop`)上,且别人可能已经拉取了代码,绝对不要 Rebase!** Rebase 会修改历史(修改 Commit ID),这会导致同事的代码与远程冲突,引发灾难。 **Rebase 仅限用于整理你自己私有的、还未合并到主干的分支。**

——

##### 5. 仓库瘦身与维护 (Garbage Collection)

Git 也是数据库,长时间使用后会有很多悬空对象(Dangling objects),占用磁盘空间。

– 手动触发垃圾回收:

压缩文件版本,移除不可达的对象,优化仓库体积。

“`Bash
git gc
“`

*通常 Git 会自动运行此命令,但手动运行可以强制立即优化。*

——

##### 6. 终极重置 (The “Nuclear” Option)

如果你的本地仓库彻底乱套了,想要完全放弃本地修改,让它变得和远程仓库(origin/main)**一模一样**:

> **⚠️ 警告:** 此操作会丢失所有本地未提交的代码!

“`Bash
# 1. 获取远程最新状态
git fetch origin

# 2. 强制重置当前分支到远程状态
git reset –hard origin/main

# 3. 清理所有未追踪文件
git clean -fd
“`

——

##### 总结建议

| **操作目的** | **常用命令** | **风险等级** |
| ———— | —————————– | ——————————— |
| **日常清理** | `git fetch -p` (同步远程删除) | 🟢 低 |
| **删除分支** | `git branch -d` | 🟢 低 |
| **清理文件** | `git clean -fd` (**先用 -n**) | 🟡 中 (文件不可找回) |
| **整理提交** | `git rebase -i` | 🟡 中 (若已推送到远程,需强制推送) |
| **重置仓库** | `git reset –hard` | 🔴 高 (丢失所有进度) |

#### 4.2.4分支操作

##### 1. 现代化命令:`switch` 与 `restore` (推荐)

Git 2.23 版本引入了两个新命令,用来替代功能过于杂乱的 `git checkout`。建议养成使用新命令的习惯,语义更清晰。

| **操作** | **旧命令 (Old)** | **新命令 (New & Recommended)** |
| —————- | ————————– | —————————— |
| **切换分支** | `git checkout <分支名>` | **`git switch <分支名>`** |
| **创建并切换** | `git checkout -b <新分支>` | **`git switch -c <新分支>`** |
| **撤销文件修改** | `git checkout <文件>` | **`git restore <文件>`** |

——

##### 2. 本地分支高频操作速查

##### 🔎 查看分支

“`Bash
# 查看本地分支(带 * 号的是当前分支)
git branch

# 查看所有分支(包含远程分支 remotes/origin/xxx)
git branch -a

# 查看分支指向的最新 commit 信息(很实用)
git branch -v
“`

##### 🛠 创建与切换

“`Bash
# 仅创建,不切换
git branch feature-login

# 切换到已存在的分支
git switch feature-login

# 创建并立刻切换过去(最常用)
git switch -c feature-login
“`

##### 🧩 合并分支 (Merge)

假设你现在位于 `main` 分支,想把 `feature-login` 的代码合进来:

“`Bash
# 1. 先切回主分支
git switch main

# 2. 执行合并
git merge feature-login
“`

> 💡 小贴士:
>
> 如果想要在合并时强制生成一个新的 Commit 节点(保留分支历史结构,而不是 Fast-forward 直线合并),请加上 –no-ff 参数:
>
> git merge –no-ff feature-login

##### ✏️ 重命名分支

如果你手滑把分支名打错了(比如把 `feature` 打成了 `future`):

“`Bash
# 重命名当前所在的分支
git branch -m <新名字>

# 重命名指定分支(不需要先切换过去)
git branch -m <旧名字> <新名字>
“`

——

##### 3. 远程分支交互 (Remote Interaction)

##### 🚀 推送分支到远程

你在本地新建了 `dev` 分支,远程仓库还没有:

“`Bash
# 第一次推送,并建立追踪关系(upstream)
git push -u origin dev
“`

*以后只需要输入 `git push` 即可。*

##### 📥 拉取远程新分支

同事在远程建立了个 `bugfix-101` 分支,你想拉到本地开发:

“`Bash
git fetch
# 直接切换,Git 会自动在本地建立同名分支并关联
git switch bugfix-101
“`

##### 🗑 删除远程分支

**注意:** 也就是删除 GitHub/GitLab 上的分支。

“`Bash
git push origin –delete <分支名>
“`

——

##### 4. 常见场景实战

###### 场景一:处理冲突 (Conflict)

当你执行 `git merge` 时,如果两个分支修改了同一行代码,Git 会报错 `CONFLICT`。

1. **打开文件**:你会看到 `<<<<<<< HEAD` 和 `>>>>>>> feature-x` 的标记。

2. **手动修改**:保留想要的代码,删除标记符号。

3. **重新提交**:

“`Bash
git add .
git commit -m “Fix merge conflicts”
“`

###### 场景二:分支游离状态 (Detached HEAD)

如果你用 `git checkout ` 切换到了某个具体的提交点,而不是分支名,你会进入“游离状态”。

– **表现**:你做的修改如果提交,一旦切走就会丢失。

– **救法**:如果你在这个状态下写了代码,想保存下来,必须立刻新建一个分支指向它:

“`Bash
git switch -c <新分支名>
“`

### 4.2.5解决冲突

#### 第一阶段:定位冲突 (Identify)

当你执行 `git merge` 或 `git pull` 出现冲突时,终端会提示 `CONFLICT (content): Merge conflict in filename`。

1. **查看冲突文件列表:** 使用以下命令查看哪些文件处于“冲突”状态:

“`Bash
git status
“`

– 输出中标记为 **`both modified`** 的文件就是你需要处理的文件。

——

#### 第二阶段:解决冲突 (Resolve)

你可以选择 **手动编辑代码** 或 **使用工具**。

##### 方法 A:手动编辑(通用方法)

1. **打开冲突文件**。你会看到 Git 自动插入的冲突标记:

Plaintext

“`
<<<<<<< HEAD var limit = 100; // 当前分支(你原本的代码) ======= var limit = 200; // 传入分支(你要合并进来的代码) >>>>>>> feature-branch
“`

– `<<<<<<< HEAD` 到 `=======` 之间:是你当前所在分支的代码。 - `=======` 到 `>>>>>>> branch-name` 之间:是另一个分支(或者远端)的代码。

2. **修改代码**。你需要做的是:

– 决定保留哪一部分(保留上面、保留下面,或者两者结合修改)。
– **删除** 所有的标记符号(`<<<<<<<`, `=======`, `>>>>>>>`)。

**修改后示例:**

“`Plaintext
var limit = 150; // 假设我们要取折中值,或者只保留某一方
“`

3. **保存文件**。

##### 方法 B:使用 IDE 工具(推荐)

如果你使用的是 VS Code、IntelliJ IDEA 或 Trae 等现代编辑器:

1. 打开冲突文件。
2. 编辑器通常会高亮显示冲突,并提供按钮:
– **Accept Current Change** (保留当前/HEAD)
– **Accept Incoming Change** (保留传入)
– **Accept Both Changes** (保留两者)
– **Compare Changes** (对比差异)
3. 点击按钮即可自动清理标记并保留选中的代码。

##### 方法 C:命令行“二选一”快捷策略

如果你确定**完全不需要**看代码,只想直接覆盖(非常暴力,慎用):

– **完全保留当前分支版本**(丢弃对方的):

“`Bash
git checkout –ours
“`

– **完全保留传入分支版本**(丢弃自己的):

“`Bash
git checkout –theirs
“`

——

##### 第三阶段:提交更改 (Commit)

解决完所有文件的冲突后,你需要告诉 Git 冲突已解决。

1. **将修改后的文件加入暂存区**(这一步是标记“冲突已解决”):

“`Bash
git add
# 或者如果都修好了
git add .
“`

2. **检查状态**: 再次运行 `git status`,确保所有文件都已变更为绿色(Ready to commit)。

3. **完成合并提交**:

“`Bash
git commit
# 通常不需要加 -m,Git 会自动生成一个 “Merge branch…” 的提交信息,直接保存退出即可
“`

*注意:如果你是在 `git rebase` 过程中遇到的冲突,请使用 `git rebase –continue` 而不是 `git commit`。*

——

### 🚨 紧急撤销 (Abort)

如果你在解决冲突的过程中把代码改乱了,或者不想合并了,可以随时**终止**这次合并,回到冲突发生之前的状态:

– 如果是合并冲突 (`merge`):

“`Bash
git merge –abort
“`

– 如果是变基冲突 (`rebase`):

“`Bash
git rebase –abort
“`

——

### 总结 Checklist

1. `git status` 找到红色的 `both modified` 文件。
2. 打开文件,搜索 `<<<<<<<`。 3. 修改代码,删除所有 Git 标记符号。 4. `git add `。
5. `git commit` (或 `git rebase –continue`)。

## 4.3 使用规范

### 1. 迭代全景图

这是一个闭环流程,通常以 1-2 周为一个周期:

“`mermaid
graph LR
A[需求规划 Planning] –> B[设计与开发 Dev]
B –> C[代码评审与合并 CR/Merge]
C –> D[测试 QA/Test]
D –> E[发布与复盘 Release/Retro]
E –> A
“`

——

### 2. 详细流程拆解

#### 第一阶段:需求规划 (Planning)

– **输入**:来自导师/老板的想法,或产品经理的需求文档 (PRD)。
– **动作**:
– **Sprint Planning 会议**:团队坐在一起,从需求池(Backlog)里挑出这 2 周能做完的任务。
– **任务拆解**:将大功能拆成具体的开发任务(Task),例如“设计数据库表”、“编写 API 接口”、“前端页面实现”。
– **估时**:评估每个任务需要多少小时。

#### 第二阶段:设计与开发 (Development) —— *Git 操作高频区*

这是你写代码的主战场。

– **切分支 (Branching)**:不要直接在 `main` 或 `master` 上写。基于主分支创建一个功能分支: `git checkout -b feature/login-module`

– **编码 (Coding)**:编写代码,实现逻辑。

– **本地自测**:运行单元测试,确保逻辑跑通。

– **处理冲突 (Rebase)**:

– 在你开发这几天,同事可能已经合并了代码到 `main`。

– **关键动作**:在提交前,先拉取最新代码并变基(这就是你刚才问的 Rebase 场景):

“`Bash
git fetch origin
git rebase origin/main
“`

– 如果有冲突,就在这里解决。

#### 第三阶段:代码评审与合并 (Code Review & Merge)

– **提交 PR/MR**:将代码推送到远程,发起 **Pull Request (GitHub)** 或 **Merge Request (GitLab)**。
– **Code Review (CR)**:
– 资深工程师或导师查看你的代码。
– 检查点:代码规范、是否有 Bug、是否这类逻辑太复杂。
– *修改*:根据评论修改代码,再次 push(会自动更新 PR)。
– **合并 (Merge)**:评审通过后,代码被合并进入 `dev` 或 `main` 分支。

#### 第四阶段:测试 (QA & Testing)

– **CI/CD 流水线**:代码合并后,自动化工具(如 Jenkins, GitHub Actions)会自动构建项目并运行自动化测试。
– **人工测试**:测试人员(QA)在测试环境(Staging)验证功能。
– 如果有 Bug -> 提单 -> 你修 Bug -> 重新走合并流程。

#### 第五阶段:发布与复盘 (Release & Retro)

– **上线 (Deploy)**:将测试通过的代码发布到生产环境(Production)。
– **回顾会议 (Retrospective)**:
– 迭代结束,团队坐下来聊聊:上个周期哪个环节卡住了?Git 冲突为什么这么多?API 文档为什么没对齐?
– 目的是为了下一次迭代更顺畅。

——

### 3. 针对个人的最佳实践 (研究生/独立开发者版)

既然你对 C++、Linux 和 AI 部署感兴趣,你的个人项目迭代可以简化为:

1. **Issue 驱动**:在 GitHub/Gitee 仓库里建 Issue,列出“今天要做的功能”。
2. **分支开发**:强迫自己用 `feature/xxx` 分支开发,**哪怕只有你一个人**。这能保护你的主分支永远是可运行的。
3. **定期 Rebase**:如果你在尝试 Trae 或其他 AI 工具协助编码,AI 生成的代码要像对待同事的代码一样,合并前仔细 Check 并解决潜在逻辑冲突。
4. **写好 Makefile/CMake**:Linux 环境下,确保你的构建脚本是自动化的,这相当于简易版的 CI/CD。![e460a993033c195c37ef46ee2904108d](/wp-content/uploads/2025/12/e460a993033c195c37ef46ee2904108d-227×300.jpg){.alignnone}

发表评论