# Git 进阶操作：版本管理，分支管理


**版本管理：**
1. **精细化历史查询**：如何只看某一个文件的修改历史。
2. **版本回退**：如何安全或强力地让文件、甚至整个知识库回到过去。
3. **内容追溯**：如何知道笔记中的某句话是何时、为何写下的。

**分支管理：**
1. **创建与切换分支**
2. **合并分支**
3. **解决文件冲突**

---

## 一、Git Log：如何查看单个文件的“成长日记”


### 核心操作

最基础的命令是在 git log 后面跟上 -- 和文件路径。-- 是一个好习惯，它能明确告诉 Git 后面跟的是文件路径，而不是分支名。

> [!bash]+ 基本用法：查看特定文件的所有 commit 记录  
> git log -- <文件路径>
> 
> **示例:**  
> git log -- "我的读书笔记.md"

### 让输出信息更友好

默认的 log 信息对非技术用户不太友好，我们可以用参数来美化它。

> [!bash]+ 单行清爽模式  
> 以单行形式展示，只看 commit 哈希值和标题，非常清爽。  
> git log --oneline -- <文件路径>

> [!bash]+ 查看修改统计  
> 展示更详细的统计信息，能看到每次提交具体增加了哪些行、删除了哪些行。  
> git log --stat -- <文件-路径>

> [!bash]+ 查看具体修改内容 (最实用)  
> 这是最强大的参数，-p 是 --patch 的缩写，它会展示每一次提交具体修改了什么内容。  
> git log -p -- <文件路径>


---


## Git 版本回退：文件级“后悔药”与提交级“时光机”

在知识管理中，我们难免会写错东西或误删内容。Git 提供了多种“后悔药”，但它们的用途和场景完全不同。对于 Obsidian 用户来说，**最常用、最重要的是针对单个文件的回退**。

首先，我们用一个表格来快速对比这三个命令的核心区别：



| 命令            | 主要作用域        | 是否修改历史                  | 核心比喻                            |
| --------------- | ----------------- | ----------------------------- | ----------------------------------- |
| **git restore** | **File (文件)**   | **否** (只修改工作区/暂存区)  | **橡皮擦** (擦掉文件的特定修改)     |
| **git revert**  | **Commit (提交)** | **否** (创建新提交)           | **会计师** (做一笔反向操作来冲账)   |
| **git reset**   | **Commit (提交)** | **是** (移动指针，可丢弃提交) | **时光机** (直接回到过去，未来消失) |

---

### 一、文件级后悔药：git restore (Obsidian 用户最常用)

git restore 是专门为**恢复文件**而生的命令，它从不触碰你的提交历史，非常安全。它有两个核心功能，覆盖了我们 95% 的日常“反悔”需求。

#### 功能1：丢弃工作区的修改 (橡皮擦)

> [!tip]+ 场景：我不小心修改了一篇笔记，但还没提交 (commit)，现在想撤销所有改动，让它恢复到上次保存到版本库时的样子。

这就像用橡皮擦擦掉你在笔记上的草稿，让它变回干净的版本。

> [!bash]+ 丢弃本地修改  
> git restore <文件路径>
> 
> **示例:**  
> git restore "我的读书笔记.md"

#### 功能2：从历史中恢复文件 (时光机捞取)

> [!tip]+ 场景：我需要找回某篇笔记在几天前某个版本的内容，但又不想影响知识库里其他任何文件。

这就像坐上时光机，去到过去，只把那一个文件“捞”回来。

> [!bash]+ 从指定 commit 中恢复文件  
> git restore --source=<commit哈希值> <文件路径>
> 
> **示例:**  
> git restore --source=1a2b3c4 "我的读书笔记.md"
> 
> 执行后，这个文件的内容就变回了 1a2b3c4 时的样子。这个“恢复”本身会成为一个新的本地修改，你可以检查后再次提交。

---

### 二、提交级后悔药：git revert 与 git reset

这两个命令更强大，也更危险，因为它们操作的对象是**整个 Commit (提交)**，会一次性影响一批文件的修改。在 Obsidian 的日常使用中，这种情况较少见，但了解它有助于应对重大失误。

> [!warning]+ 核心区别
> 
> - git revert 和 git reset **针对的是整个提交记录**，不是单个文件。
>     
> - 如果你只是想恢复某个文件，请永远优先使用 git restore。
>     
> - 如果你确定要撤销一整批修改（一个 Commit），那么更推荐使用 git revert。
>     

#### The Safe Choice: git revert (安全的会计师)

它通过创建一个**新的提交**来抵消旧的错误提交，**不会修改历史**，非常安全。

> [!success]+ git revert (推荐)
> 
> - **比喻**：像会计师做一笔反向操作来冲账，所有记录都清晰可查。
>     
> - **场景**：当你需要撤销一个已经推送到远程（如 Gitee/GitHub）的提交时，**这是唯一推荐的做法**。
>     
> - **命令**：git revert <commit哈希值>
>     

#### The Nuclear Option: git reset (危险的时光机)

它会**真实地修改历史**，让你的知识库强制回到过去某个时间点，之后的提交记录会被抛弃。

> [!danger]+ git reset (谨慎使用)
> 
> - **比喻**：像启动时光机，回到过去，之后发生的一切都烟消云散。
>     
> - **场景**：**只应在你自己本地、还未推送分享的提交上使用**，用来清理凌乱的本地历史。**绝对不要**对已推送的提交使用！
>     
> - **命令**：git reset --hard <commit哈希值>
>


---

## 三、Git Blame：甩锅！

这个功能的名字有点吓人，但对于知识管理来说，它不是用来“指责”(Blame)，而是用来“追溯”的。**（如果是软件开发：那我就是来甩锅的）**

### 核心操作

> [!bash]+ git blame 命令行操作  
> git blame <文件路径>
> 
> **示例:**  
> git blame "项目A策划案.md"

它的输出会显示文件的每一行内容，并在行首标注出：修改这一行的 commit 哈希值、作者、以及修改日期。


---


# Git 分支管理核心命令笔记



分支是 Git 的最强大的功能，它允许你创建独立的开发线进行工作，做到平行开发，互不干扰。



### 一、查看与切换分支

> [!bash]+ 列出所有本地分支  
> git branch
> 
> 当前所在的分支会以 * 标记。

> [!bash]+ 创建新分支  
> git branch <分支名>
> 
> **示例:** git branch feature/new-article
> 
> 这只创建了分支，你当前的位置**并未**移动。当前在main分支下，就是从main分支下创建出一个新分支，但你依然停留在main分支下，你需要手动切换到这个新分支。
> 
> **从指定分支中，创建一个分支**：git branch <新分支名> <源分支>
> 比如：git branch hotfix/login-bug main 意思就是从main分支中，创建一个叫hotfix/login-bug的新分支。
> 对于个人Obsidian用户，大多情况下都在main分支上，想要创建新分支就直接用git branch <分支名>就可以了

> [!bash]+ 切换到指定分支  
> git switch <分支名>
> 
> **示例:** git switch feature/new-article
> 
> 这是推荐的现代命令。旧命令 git checkout <分支名> 同样有效。

> [!tip]+ 创建并立即切换 (常用)  
> git switch -c <分支名>
> 
> **示例:** git switch -c bugfix/typo-in-note
> 
> 这一个命令等同于 git branch 和 git switch 两步操作。

---

### 二、合并与删除分支

当分支的工作完成后，将其成果合并回主线 (main 或 master)。

> [!info]+ 合并分支的标准流程
> 
> 1. **首先，切换回你的主分支。**  
>     git switch main
>     
> 2. **然后，执行合并命令，将目标分支的成果合并进来。**  
>     git merge <要合并的分支名>  
>     **示例:** git merge feature/new-article
>     

> [!bash]+ 删除已合并的分支  
> git branch -d <分支名>
> 
> **示例:** git branch -d feature/new-article
> 
> -d 是 --delete 的缩写，它会安全地检查该分支是否已被合并。如果有没有被合并的修改，它会阻止删除。

---

### 三、解决合并冲突

当你和主分支修改了同一个文件的同一处时，git merge 会失败并提示冲突。

> [!danger]+ 解决冲突的标准流程
> 
> 1. **打开冲突文件。** Git 会在文件中用特殊标记标出冲突区域：  
>     <<<<<<< HEAD (你当前分支的修改)  
>     =======  
>     >>>>>>> <另一分支名> (被合并分支的修改)
>     
> 2. **手动编辑文件。** 删除所有 Git 添加的特殊标记行，只保留你最终想要的内容。
>     
> 3. **标记冲突已解决。** 使用 git add 命令将修改后的文件加入暂存区。  
>     git add <冲突文件的路径>
>     
> 4. **完成合并。** 执行 git commit 命令，Git 会自动生成一个合并提交信息，直接保存即可。此时，冲突解决完毕。
>

> **专注 AI 与个人知识管理**
> 本文属于 [杰森的效率工坊](https://jasonai.me)原创。未经允许禁止商用。
> 
> **订阅杰森的频道：**
> [YouTube](https://www.youtube.com/@JasonEfficiencyLab) · [Twitter(X)](https://x.com/JasonEffiLab) · [小红书](https://www.xiaohongshu.com/user/profile/60935957000000000101fbf7) · [B站](https://space.bilibili.com/3546884870244925)