#Git 变基(Rebase)案例

适合学习理解的 Git 变基(Rebase)案例

为了帮助你更好地理解 Git 变基(Rebase)的操作和效果,下面通过一个简单的案例来演示变基的过程和影响。


案例背景

假设我们有一个 Git 仓库,包含两个分支:

  • 主分支(main):包含最新的稳定代码。
  • 特性分支(feature) :开发新功能的分支,从 main 分支的某个旧提交创建。
初始提交历史
复制代码
A --- B --- C --- D  (main)
      \
       E --- F --- G  (feature)
  • A、B、C、D :main 分支的提交。
  • E、F、G :feature 分支的提交,基于 main 分支的提交 B。
场景

在 feature 分支开发期间,main 分支有了新的提交 C 和 D。现在,我们希望将 feature 分支的变更应用到 main 分支的最新提交 D 之后,使提交历史更加线性。


变基操作步骤

1. 切换到 feature 分支
bash 复制代码
git checkout feature
2. 执行变基操作
bash 复制代码
git rebase main
3. Git 的操作过程
  • 找到共同祖先 :Git 找到 feature 分支和 main 分支的共同祖先提交 B。
  • 应用提交 :将 feature 分支上的每个提交(E、F、G)依次应用到 main 分支的最新提交 D 之后。
  • 解决冲突(如果有):如果在应用提交时遇到冲突,需要手动解决冲突后继续变基。
4. 变基完成后的提交历史
复制代码
A --- B --- C --- D  (main)
                  \
                   E' --- F' --- G'  (feature)
  • E'、F'、G' :变基后的新提交,基于 main 分支的最新提交 D。
  • 原提交 E、F、G:被新提交 E'、F'、G' 替代,提交哈希值发生变化。

详细步骤演示

步骤 1:创建初始提交历史
bash 复制代码
# 初始化仓库
git init

# 创建 main 分支并提交
git checkout -b main
echo "Initial commit" > file.txt
git add file.txt
git commit -m "A"

echo "Second commit" >> file.txt
git add file.txt
git commit -m "B"

echo "Third commit" >> file.txt
git add file.txt
git commit -m "C"

echo "Fourth commit" >> file.txt
git add file.txt
git commit -m "D"

# 创建 feature 分支并提交
git checkout -b feature HEAD~3  # 基于提交 B 创建分支
echo "Feature commit 1" >> file.txt
git add file.txt
git commit -m "E"

echo "Feature commit 2" >> file.txt
git add file.txt
git commit -m "F"

echo "Feature commit 3" >> file.txt
git add file.txt
git commit -m "G"
步骤 2:执行变基操作
bash 复制代码
# 切换到 feature 分支
git checkout feature

# 变基到 main 分支
git rebase main
步骤 3:查看变基后的提交历史
bash 复制代码
# 查看提交历史
git log --oneline --graph --all

输出示例:

复制代码
* 1234567 (HEAD -> feature) G' - Feature commit 3
* 2345678 F' - Feature commit 2
* 3456789 E' - Feature commit 1
* 4567890 (main) D - Fourth commit
* 5678901 C - Third commit
* 6789012 B - Second commit
* 7890123 A - Initial commit

案例解析

1. 变基前
  • feature 分支的提交 E、F、G 基于 main 分支的旧提交 B。
  • 提交历史呈现分支结构,不够线性。
2. 变基后
  • feature 分支的提交 E'、F'、G' 基于 main 分支的最新提交 D。
  • 提交历史变得线性,易于阅读和理解。
3. 提交哈希值变化
  • 变基会重写提交历史,导致提交哈希值发生变化(如 E 变为 E')。
  • 这也是变基不适用于已推送的共享分支的原因。

类比理解

类比 :

想象你正在写一本小说,main 分支是主线剧情,feature 分支是支线剧情。

  • 变基前:支线剧情基于主线剧情的某个旧章节。
  • 变基后:你将支线剧情的修改应用到主线剧情的最新章节之后,使整个故事更加连贯。

注意事项

  1. 不要在已推送的共享分支上使用 rebase :

    如果 feature 分支已经推送到远程仓库,并且其他开发者基于该分支进行了开发,使用 rebase 会导致提交历史不一致,引发问题。

  2. 备份分支 :

    在进行 rebase 操作前,建议创建分支备份,以防出现问题。

  3. 理解提交历史 :
    rebase 会改变提交历史,需要理解其影响,避免误操作。


总结

  • 变基(Rebase):将当前分支的变更应用到目标分支的最新提交之后,使提交历史更加线性。
  • 案例演示 :通过 feature 分支变基到 main 分支,展示了变基的操作和效果。
  • 适用场景:本地开发分支整合、清理提交历史。
  • 注意事项 :如果分支已经推送到远程仓库,其他开发者可能已经基于该分支的提交进行了开发。变基后,提交历史发生变化,导致其他开发者的本地仓库与远程仓库不一致。 不要对已经推送的记录进行变基!

变基之后仍然存在两个分支,但 feature 分支的基准点(base)发生了变化。具体来说,feature 分支原来是基于 main 分支的提交 B,变基后变成了基于 main 分支的最新提交 D。

图片中, 右边 在dev分支上 变基


变基后合并操作的步骤

1. 前提条件
  • 已完成变基 :假设你已经对某个分支(如 feature 分支)执行了 git rebase main,使其基于 main 分支的最新提交。
  • 目标分支 :你希望将变基后的 feature 分支合并到 main 分支。
2. 切换到目标分支
bash 复制代码
git checkout main
  • 目的:确保你在要合并到的目标分支上。
3. 更新目标分支
bash 复制代码
git pull origin main
  • 目的:确保目标分支是最新的,避免合并冲突。
4. 合并变基后的分支
bash 复制代码
git merge feature
  • 情况 1 :如果变基后没有冲突,Git 会自动完成合并,生成一个合并提交(如果使用 --no-ff 选项)。
  • 情况 2:如果有冲突,Git 会提示你解决冲突。
5. 解决冲突(如果有)
  • 查看冲突文件 :

    bash 复制代码
    git status
  • 手动编辑冲突文件 :解决冲突后,标记冲突已解决:

    bash 复制代码
    git add <conflicted-file>
  • 完成合并 :

    bash 复制代码
    git commit
6. 推送更新到远程仓库
bash 复制代码
git push origin main
  • 目的:将合并后的更改推送到远程仓库。

变基后合并的注意事项

  1. 确保变基已完成且无冲突:

    • 在合并前,确保 feature 分支已经成功变基到 main 分支的最新提交。
    • 解决变基过程中可能出现的冲突。
  2. 避免在已推送的共享分支上变基:

    • 如果 feature 分支已经推送到远程仓库,并且其他开发者基于该分支进行了开发,变基可能导致问题。
    • 建议:在本地分支上变基,合并前与其他开发者沟通。
  3. 使用 --no-ff 选项(可选):

    • 合并时可以使用 --no-ff(no fast-forward)选项,保留分支历史,便于查看合并记录。
    bash 复制代码
    git merge --no-ff feature
  4. 备份重要分支:

    • 在进行合并操作前,建议备份重要分支,以防出现问题。

变基后合并的优势

  • 线性提交历史:变基后,提交历史更加线性,易于阅读和理解。
  • 减少合并提交 :如果变基成功,合并时可能不会产生额外的合并提交(取决于是否使用 --no-ff)。
  • 清晰的开发流程:通过变基和合并,可以保持代码库的整洁和一致性。

变基后合并的示例

场景描述
  • 初始状态 :
    • main 分支:A --- B --- C --- D
    • feature 分支:A --- B --- E --- F --- G(基于 B)
  • 变基后 :
    • feature 分支:A --- B --- C --- D --- E' --- F' --- G'(基于 D)
合并操作
  1. 切换到 main 分支:

    bash 复制代码
    git checkout main
  2. 更新 main 分支:

    bash 复制代码
    git pull origin main
  3. 合并 feature 分支:

    bash 复制代码
    git merge feature
  4. 解决冲突(如果有):

    • 编辑冲突文件,标记解决,完成合并。
  5. 推送更新:

    bash 复制代码
    git push origin main
  6. 最终提交历史:

    复制代码
    A --- B --- C --- D --- E' --- F' --- G'  (main, feature)

相关推荐
csdn2015_2 小时前
git多分支切换修改
git
小巫山云子4 小时前
Git的用法
大数据·git·elasticsearch
开发者联盟league4 小时前
git pull拉取失败UNPROTECTED PRIVATE KEY FILE
git
殷紫川5 小时前
Git Worktree 深度实战:从底层原理到 Java 开发效率翻倍指南
git
zttbee19 小时前
git命令
git
mister_guo2 天前
开发指南:Git日常维护与常用命令
git
鶴哥只手遮天2 天前
Git 2.56 源码深度剖析:为 Git 3.0 铺路的架构重构
git·开源
小此方2 天前
「插曲:Git」标签管理篇:理解Tag标签、为指定提交打标签、查看标签详情与附注标签
git
Madison-No72 天前
多语言聊天大模型--测试报告
linux·git·python·selenium·jmeter·自动化·postman
小此方2 天前
「插曲:Git」多人协作篇:远程分支创建与关联、多人协作冲突解决、Feature分支开发与合并、git remote prune清理失效分支
git