说明
本篇文章是为了理解git rebase
命令而写,也是对Pro Git 3.6 Git 分支 - 变基 章节的总结。
什么是变基?
使用rebase命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样(将一个分支的修改操作在另一个分支最新的提交基础上在依次应用)。
变基的目的?
一般我们这样做的目的是为了确保在向远程分支推送时能保持提交历史的整洁——例如向某个其他人维护的项目贡献代码时。 在这种情况下,你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到 origin/master 上,然后再向主项目提交修改。 这样的话,该项目的维护者就不再需要进行整合工作,只需要快进合并便可。
怎样使用变基?
git rebase branch-name。例如在iss33分支执行git rebase master表示将iss33分支的commit对象在master分支重放一次(依次应用)。
变基原理?
通过一个事例来说明变基的原理。假设我们有一个master分支,master分支已经有了三次提交(7c3eefb、f9318aa、f9318aa)。捡出iss33分支,分别在master和iss33分支进行修改a.txt文件并提交到对应的分支本地仓库中(如图:在master分支上捡出iss33分支,并在两个分支各做一次commit)。
捡出iis33分支(git checkout iss33),执行 git rebase master,这时Git会找到master和iss33最近一个共同的父commit对象,并找出这个共同的父commit对象到iss33分支最新提交对象之间的所有对象,将这些对象在master分支最新一次提交依次应用。这个过程很像将一个数组追加到另一个数组。这时我们git rebase master会提示有冲突(因为我们在master和iss33都修改了a.txt,并且是同一行代码),对冲突文件进行手工合共,然后git add .标记冲突解决,git rebase --continue告诉Git冲突已经解决。整个rebase过程完成后提交历史如图:在iss33分支上变基(git rebase master)。通过提交历史可以看到这时我们回到msater分支执行 git merge iss3就可以进行"快进(fast-forward)"模式合并。
注意:git rebase master之后iss33最新的提交从97df2346变成了023c0fb,说明rebase重新生成了一个新commit对象替换原来的commit对象。变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。
变基过程中常用的几个命令
例如我们需要将iss33变基到master分支上,使用命令git checkout iss33;git rebase master
,此时会进入rebase模式,如果iss33和master分支中的提交有冲突,需要手动合并文件解决,解决冲突后使用git add
表示冲突已经解决,git rebase --continue
表示继续下一个冲突,git rebase --skip
表示跳过当前冲突,git rebase --abort
表示退出rebase模式,回到运行git rebase master
命令之前的状态。
什么情况下应该避免使用变基?
不应该对已经推送到远程仓库的提交历史进行rebase操作——————切记。
比如我们将合并后的dev和master分支提交历史推送到了远程仓库。
(合并历史记录)
C3->C4-dev
/
/
C1->C2->C5-master
提交里推送到了远程仓库,然后发现记录不够简洁,我们在本地进行rebase,然后再git push --force覆盖远程仓库上的推送。–不要这样使用rebase,切记。
(rebase历史记录)
C1->C2->C5->CC3’->CC4’-master-dev