《Pro Git》
读书笔记整理指正
,书很不错,感兴趣小伙伴可以去拜读
下傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波
在 Git 中整合来自不同分支的修改主要有两种方法:merge 以及 rebase。
之前介绍过,整合分支最容易的方法是 merge 命令。它会把两个分支的最新快照(C3 和 C4)以及二者最近的共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(并提交)。
其实,还有一种方法:你可以提取在C4中引入的补丁和修改,然后在C3的基础上应用一次。在Git中,这种操作就叫做 变基(rebase)
,可以用于完善主分支的提交历史。分支合并的话,主分支上不体现其他分支的提交历史。
你可以使用rebase命令将提交到某一分支上的所有修改都移至另一分支上,就好像 “重新播放”
一样。在这个例子中,你可以检出 experiment 分支,然后将它变基到 master 分支
上:
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
它的原理是:
现在回到 master 分支,进行一次快进合并。
$ git checkout master
$ git merge experiment
此时,C4’指向的快照就和the merge example中C5指向的快照一模一样了。这两种整合方法的最终结果没有任何区别,但是 变基使得提交历史更加整洁
。
你在查看一个经过变基的分支的历史记录时会发现,尽管实际的开发工作是并行的,但它们看上去就像是串行的一样,提交历史是一条直线没有分叉。
一般我们这样做的目的是为了确保在向远程分支推送时能保持提交历史的整洁
请注意,无论是通过变基,还是通过三方合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在。
在对两个分支进行变基时,所生成的“重放”并不一定要在目标分支上应用,你也可以指定另外的一个分支进行应用。
你创建了一个主题分支 server,为服务端添加了一些功能,提交了 C3 和 C4。然后从 C3 上创建了主题分支 client,为客户端添加了一些功能,提交了 C8 和 C9。最后,你回到 server 分支
,又提交了 C10。
假设你希望将 client 中的修改合并到主分支并发布,但暂时并不想合并 server 中的修改, 因为它们还需要经过更全面的测试。这时,你就可以使用 git rebase
命令的 --onto
选项, 选中在 client 分支里但不在 server 分支里的修改(即 C8 和 C9),将它们在 master 分支上重放:
$ git rebase --onto master server client
以上命令的意思是:“取出 client 分支,找出它从 server 分支分歧之后的补丁, 然后把这些补丁在 master 分支上重放一遍,让 client 看起来像直接基于 master 修改一样”。
现在可以快进合并 master 分支了。(如图 快进合并 master 分支,使之包含来自 client 分支的修改)
$ git checkout master
$ git merge client
接下来你决定将 server 分支中的修改也整合进来。使用 git rebase <basebranch> <topicbranch>
命令可以直接将主题分支 (即本例中的 server)变基到目标分支(即 master)上。这样做能省去你先切换到server 分支,再对其执行变基命令的多个步骤。
$ git rebase master server
$ git checkout master
$ git merge server
至此,client 和 server 分支中的修改都已经整合到主分支里了, 你可以删除这两个分支,最终提交历史会变 成图 最终的提交历史 中的样子:
$ git branch -d client
$ git branch -d server
如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git rebase 命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交,事情就会变得一团糟。
提交历史到底意味着什么?
到底合并还是变基好?
总的原则是,只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作,这样,你才能享受到两种方式带来的便利。
《Pro Git》