第四章 分支 —— Git 的杀手级特性
4.1 理解分支模型
分支本质上是一个指向提交对象(commit)的可移动指针。Git 的默认分支名为 master 或 main。
master 分支
|
v
C0 --- C1 --- C2 --- C3 (HEAD->master)
创建新分支时,只是创建了一个新的指针:
C0 --- C1 --- C2 --- C3 (HEAD->master, develop)
切换分支后,工作目录会变成该分支的最新快照。
4.2 基本分支操作
# 列出所有本地分支(当前分支带 *)
git branch
# 列出远程分支
git branch -r
# 列出所有分支(本地+远程)
git branch -a
# 创建新分支(但不会切换)
git branch feature-login
# 切换到一个分支
git checkout feature-login
# 或使用新命令
git switch feature-login
# 创建并切换到新分支(一步到位)
git checkout -b feature-login
git switch -c feature-login
# 删除分支(必须确保不在该分支上)
git branch -d feature-login # 已合并的分支
git branch -D feature-login # 强制删除未合并的分支
# 重命名当前分支
git branch -m new-name
# 重命名任意分支
git branch -m old-name new-name
4.3 合并(Merge) —— 整合分支
# 首先切换到目标分支(例如 master)
git checkout master
# 将另一个分支(例如 feature)合并到当前分支
git merge feature
# 合并时创建合并提交(非快进模式)
git merge --no-ff feature
合并类型:
快进合并(Fast-forward):目标分支直接是源分支的后继,指针直接移动。
Before: master → C1 → C2
feature → C3 (基于C2)
After (fast-forward): master → C1 → C2 → C3 (master 指向 C3)
三方合并(3-way merge):两个分支有分叉,Git 自动创建一个新的合并提交。
Before: C1 → C2 → C4 (master)
\
→ C3 (feature)
After: C1 → C2 → C4 → C5 (merge commit)
\ /
→ C3 ---
4.4 合并冲突解决
当两个分支修改了同一文件的同一行,或者一个分支删除了另一个分支修改的文件时,Git 无法自动合并,产生冲突。
示例冲突:
$ git merge feature
Auto-merging hello.py
CONFLICT (content): Merge conflict in hello.py
Automatic merge failed; fix conflicts and then commit the result.
冲突标记:
<<<<<<< HEAD
print("Hello from master")
=======
print("Hello from feature")
>>>>>>> feature
解决步骤:
手动编辑冲突文件,删除标记,保留最终需要的代码
git add 标记为已解决
git commit 完成合并提交
# 使用工具解决冲突
git mergetool # 会打开配置的合并工具(如 vimdiff, kdiff3)
# 取消本次合并(回到合并前状态)
git merge --abort
模拟冲突场景:
# 创建并切换到 feature 分支
git checkout -b feature
echo "Feature line" > test.txt
git add test.txt && git commit -m "feature: add test.txt"
# 切回 master,修改同一文件
git checkout master
echo "Master line" > test.txt
git add test.txt && git commit -m "master: add test.txt"
# 合并冲突
git merge feature
# 解决冲突后提交
4.5 变基(Rebase) —— 另一种整合方式
git rebase 将一系列提交按顺序“复制”到另一个分支的顶端,使历史变成线性。
# 在 feature 分支上执行
git checkout feature
git rebase master
# 效果:将 feature 分支中从 master 分叉后的所有提交,应用到 master 的最新提交之后
合并前(分叉):
C1 --- C2 (master)
\
C3 --- C4 (feature)
执行 git rebase master 后:
C1 --- C2 (master)
\
C3' --- C4' (feature) # C3' 和 C4' 是新的提交对象
然后切换到 master 执行 fast-forward 合并:
git checkout master
git merge feature # 现在是快进合并
变基与合并的对比:
黄金法则:不要对已经推送到远程仓库的分支执行 rebase! 否则会导致他人基于旧分支的工作混乱。
4.6 交互式变基(Interactive Rebase) —— 修改历史
# 对最近 3 个提交进行交互式变基
git rebase -i HEAD~3
会打开编辑器,列出提交列表,你可以对每个提交执行操作:
pick 7c6a5b8 Add login feature
pick 3a7c8f9 Fix typo in login
pick 2b9d4e1 Add logout feature
# Rebase 2b9d4e1..7c6a5b8 onto 2b9d4e1
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# d, drop = remove commit
常用操作:
squash:将当前提交合并到前一个提交
reword:修改提交信息
edit:修改提交内容(如添加遗漏文件)
drop:删除提交
示例:合并最后两个提交为一个
pick abc123 Add feature
squash def456 Fix typo
保存后,可以编辑合并后的提交信息。
来源:
http://aescc.cn/