#Git 变基(Rebase)案例

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

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


案例背景

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

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

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


变基操作步骤

1. 切换到 feature 分支
bash 复制代码
git checkout feature
2. 执行变基操作
bash 复制代码
git rebase main
3. Git 的操作过程
  • 找到共同祖先 :Git 找到 feature 分支和 main 分支的共同祖先提交 B
  • 应用提交 :将 feature 分支上的每个提交(EFG)依次应用到 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 分支的提交 EFG 基于 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)

相关推荐
Naomi5211 小时前
自定义汇编语言(Custom Assembly Language) 和 Unix & Git
服务器·开发语言·git·unix
@BreCaspian3 小时前
Git 从入门到精通(开源协作特别版)
git·开源
谢尔登5 小时前
【已解决】Webstorm 每次使用 git pull/push 都要输入令牌/密码登录
ide·git·webstorm
紫阡星影6 小时前
TortoiseGit多账号切换配置
git·gitee·tortoisegit
予早6 小时前
git kex_exchange_identification 相关问题
git
鸠摩智首席音效师7 小时前
如何完整迁移 Git 仓库 ?
git
诚诚程程成11 小时前
git配置github
git·github
阿杜杜不是阿木木11 小时前
使用ollama部署本地大模型(没有GPU也可以),实现IDEA和VS Code的git commit自动生成
linux·git·vscode·ai·intellij-idea·ollama
HelloDam14 小时前
Git简洁安装方式和使用方式【附安装包资源,Git基础操作,如拉取项目、上传代码、拉取代码】
git·github
咖啡教室1 天前
日常开发中常用的git操作命令和使用技巧
git