Skip to content
Chapter 04

分支管理

掌握 Git 分支的创建、切换、合并与变基,理解快进合并与三方合并的区别,学会用 rebase 重写历史。

分支基础

如何创建、切换和删除分支?

使用 git branch <name> 创建新分支,git switch <name> 或 git checkout <name> 切换分支,git branch -d <name> 删除已合并的分支。

$ git branch feature        # 创建分支
$ git switch feature        # 切换到 feature 分支
$ git branch -d feature     # 删除已合并的分支
如何查看本地和远程分支?

git branch 查看本地分支,git branch -a 查看所有分支(包括远程)。远程分支用红色标注,以 remotes/ 开头。当前所在分支前会有 * 标记。

$ git branch
* main
  feature

$ git branch -a
* main
  feature
  remotes/origin/main
  remotes/origin/feature
git checkout -b 和 git switch -c 有什么区别?

两者功能完全相同,都是创建并切换到新分支。git switch 是 Git 2.23(2019年)引入的新命令,专门用于分支切换,语义更清晰。推荐使用 git switch -c。

$ git checkout -b feature   # 旧写法,依然有效
$ git switch -c feature     # 新写法,推荐使用
分支操作练习
欢迎使用 Git 终端模拟器!按照步骤提示操作,或输入 help 查看可用命令。
$

合并与变基

git merge 是做什么的?

git merge <branch> 将指定分支的更改合并到当前分支。合并时会自动寻找两个分支的共同祖先,进行三方比较后生成合并结果。

$ git switch main
$ git merge feature     # 将 feature 合并到 main
什么是快进合并(fast-forward)?

当被合并分支是当前分支的直接后续(即当前分支没有新提交)时,Git 只需将指针向前移动,不需要产生 merge commit。这种合并方式历史看起来是线性的。

# main 没有新提交,feature 是 main 的直接后续
$ git merge feature
Updating a1b2c3d..e4f5g6h
Fast-forward
 feature.js | 5 +++++
 1 file changed, 5 insertions(+)
什么是三方合并?

当两个分支都有新的提交时,Git 会找到它们的共同祖先(base),然后对三个版本(base、当前分支、被合并分支)进行三方比较,自动合并并产生一个 merge commit。如果同一位置都有修改,则会产生冲突,需要手动解决。

--no-ff 参数有什么用?

git merge --no-ff <branch> 禁止快进合并,即使可以快进也强制产生 merge commit。这样可以保留分支的存在痕迹,让历史更清晰地展示"这里有一个分支被合并了"。

$ git merge --no-ff feature
Merge made by the 'ort' strategy.
 feature.js | 5 +++++
 1 file changed, 5 insertions(+)
git rebase 和 git merge 有什么区别?

git merge 保留分支的分叉历史,产生 merge commit。git rebase 则将当前分支的提交"重新播放"到目标分支之上,使历史变成线性的。rebase 的历史更干净,但它改写了提交历史(commit hash 会变)。

# merge: 保留分叉
$ git merge feature

# rebase: 线性历史
$ git rebase main
什么时候用 merge,什么时候用 rebase?

公共分支(如 main、develop)用 merge,因为公共分支的历史不应被改写。私有/特性分支用 rebase,可以保持提交历史整洁线性。简单来说:在你推送到远程之前,可以用 rebase 整理提交;一旦推送了,就用 merge。

Rebase 黄金规则

永远不要对已经推送到远程的公共分支执行 rebase!因为 rebase 会重写 commit hash,其他协作者的历史将与你冲突,导致混乱。如果公共分支需要整合,请使用 merge。

git commit --amend 是做什么的?

修改最近一次提交的消息或内容。如果你忘记添加某个文件或想修改 commit message,可以用 --amend。它会将暂存区的内容合并到上一次提交中,并允许你修改提交消息。

$ git add forgotten-file.js
$ git commit --amend -m "更准确的提交消息"
git rebase -i 交互式变基有什么用?

交互式变基允许你整理提交历史,常用操作包括:

  • pick — 保留该提交
  • squash — 将该提交合并到前一个提交
  • reword — 修改提交消息
  • reorder — 调整提交顺序(通过移动行)
  • drop — 丢弃该提交(删除该行)
$ git rebase -i HEAD~3   # 整理最近 3 个提交
git cherry-pick 是做什么的?

git cherry-pick <commit-hash> 将指定的提交应用到当前分支。适用于只想要某个分支上的特定修改,而不需要合并整个分支的场景。

$ git cherry-pick a1b2c3d   # 将 a1b2c3d 这个提交应用到当前分支
git reset --soft、--mixed、--hard 有什么区别?

三者都移动分支指针,但影响范围不同:

# --soft: 只移动指针,工作区和暂存区不变
$ git reset --soft HEAD~1

# --mixed: 移动指针 + 取消暂存(默认模式)
$ git reset --mixed HEAD~1
# 等同于 git reset HEAD~1

# --hard: 移动指针 + 丢弃所有修改(危险!)
$ git reset --hard HEAD~1
警告:git reset --hard 会丢失数据

git reset --hard 会永久丢弃所有未提交的修改和工作区文件变更,且无法通过常规方式恢复。使用前请确认你真的不需要这些更改。如果只是想撤销提交但保留修改,请使用 --soft 或 --mixed。

合并与变基练习
本练习已预置 main 和 feature 两个分支,各有一个提交。
按照步骤体验 fast-forward 和 --no-ff 合并的区别。
$