Git rebase

163 阅读3分钟

1 什么是 "rebase 变基"

📍 整合不同分支间的变更,当执行Git 分支 - 变基操作时,git会从两个分支的共同祖先开始提取待变基分支上的修改,然后将待变基分支指向基分支的最新提交,最后将刚才提取的修改应用到基分支的最新提交的后面。

📌 使用方法:

# basebranch  —— 基线分支(master)
# topicbranch —— 主题分支(feature)

git rebase basebranch 

# 可以节省先 checkout 到 topicbranch 的步骤
git rebase <basebranch> <topicbranch>
  • rebase 命令可以只有一个参数,从而省略第二个参数 待变基 主题分支

2 rebase 变基 的基本操作

git_rebase_branch.png

  1. 切换到experiment分支

    git checkout experiment
    
  2. 执行变基操作

    git rebase master
    # 此处我们使用了带有一个参数的命令
    # 如果使用带有两个参数的命令则是:git rebase master experiment
    
    • 首先找到这两个分支(当前分支experiment,变基操作的目标基线分支 master)最近共同祖先commit节点 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件, 然后将当前分支指向目标基底 C3, 最后以此将之前另存为临时文件的修改依序应用。

git_rebase.png

  1. 将 C4 中的修改变基到 C3 上

    git checkout master
    # 进行一次快进合并, 此时 master -> C4
    git merge experiment
    

git_rebase_merge.png

2.1 交互式变基

git rebase -i HEAD~3

🎺 此命令将打开一个编辑器,列出最近的 3 次提交,并允许你对它们进行以下操作

操作描述
pick保留提交(默认)
reword修改提交信息
edit修改提交内容(可用于拆分提交)
squash / s合并到前一个提交
fixup / f合并到前一个提交,丢弃提交信息
exec / x在该提交后运行 shell 命令
drop / d删除提交

3 多重主题分支

📢 你创建了一个主题分支 server,为服务端添加了一些功能,提交了 C3 和 C4。 然后从 C3 上创建了主题分支 client,为客户端添加了一些功能,提交了 C8 和 C9。 最后,你回到 server 分支,又提交了 C10

git_rebase_3_branch.png

🤷‍♂️ 假设你希望将 client 中的修改合并到主分支并发布,但暂时并不想合并 server 中的修改, 因为它们还需要经过更全面的测试

  1. 可以使用 git rebase 命令的 --onto 选项, 选中在 client 分支里但不在 server 分支里的修改(即 C8 和 C9),将它们在 master 分支上重放,截取主题分支上的另一个主题分支,然后变基到其他分支

     git rebase --onto master server client
    
    • 以上命令的意思是:“取出 client 分支,找出它从 server 分支分歧之后的补丁, 然后把这些补丁在 master 分支上重放一遍,让 client 看起来像直接基于 master 修改一样”

git_rebase_onto.png

  1. 快进合并 master 分支, 使之包含来自 client 分支的修改

    git checkout master
    git merge client
    

git_rebase_onto_merge.png

  1. 整合另一个主题分支 server,使用 git rebase <basebranch> <topicbranch>

     # 当前在 master 分支
     # 这样做能省去你先切换到 `server` 分支,再对其执行变基命令的多个步骤
     git rebase master server
    

git_rebase_server.png

  1. 快进合并主分支 master

     git checkout master
     git merge server
    

git_rebase_server_merge.png

  1. 至此,client 和 server 分支中的修改都已经整合到主分支里了, 你可以删除这两个分支,最终提交历史会变成图 最终的提交历史 中的样子:

     git branch -d client
     git branch -d server
    

  1. git merge 时候如何处理已经cherry-pick 过的记录呢
  2. 这一次彻底搞懂 Git Rebase
  3. git的使用中,merge与rebase的区别
  4. git中rebase(变基)和merge(合并)区别
  5. git merge after git cherry-pick: avoiding duplicate commits