TIC2019GitTrain

TIC·2019年Git培训资料

View project on GitHub

第三章(进阶1) 干净的仓库历史

阅读资料:git-recipes: 5.1-代码合并Merge还是Rebase.md

我无意于重复已经存在的教程信息,只准备简单列出本次培训中各位所需要知道的精简信息。 如果你有兴趣,请移步阅读资料中的超链接,更加系统性地进行学习。

要流畅阅读本章,你应该对 第二章:Git的基本使用第三章:多人协同开发有较好的理解。

  • 本章你将了解到各种Git工作流,即如何科学地使用Git进行多人协同工作。

  • 本章将会讲授一种很容易让萌新感到困惑的操作git rebase,如果你暂时无法理解这个内容,请跳过这些内容,在更多的接触Git之后,再回来阅读。

保持历史纪录的整洁是非常重要的

在之前的学习中我们了解到.gitignore,它可以使你的仓库变得整洁。 之所以这么强调整洁,这是因为基于Git的开发是一个多人环境,复杂、难以理解和重复的非必需内容容易让人感到困惑,进而拖慢整个团队的开发效率。

本小节将会讲到一个重要的指令:git rebase(或git merge --rebase)。

这是非常容易让萌新感到困惑的内容,目前阶段你需要知道,保持一个干净而整洁的仓库历史记录、消除过多无用的commit记录是非常必要的,而上述命令就是用以实现这个需求的方法。你可以暂时跳过本节,待你在更多地接触Git之后,再回来阅读。


我们先来说说几条黄金法则:

  • 黄金法则① 过多的无用提交记录将会拖垮整个团队的开发效率。
  • 黄金法则② 永远不要对远程仓库上的分支进行整理,除非团队中有人主导这项工作。而相应的,每个人应该在向远程仓库push自己的内容前做好分支整理/仓库历史整理,或是在pull request时由他人做好code review工作。
  • 黄金法则③ 谨慎使用git rebase,否则你将丢失大部分仓库历史,一定程度上有可能导致代码的丢失。出于历史记录的可阅读性考虑,引入pull requese时请尽量使用merge
  • 黄金法则④ 不要对你已推送为远程(公共)分支的本地分支进行rebase操作。

变基操作

先来说说git rebase,也就是变基操作。

什么是基(base)?如下图所示,几个分支或几条记录共同的祖先,就叫做”基”:(下图显示的是两个分支的基)

① 单分支记录合并(合并多条重复记录)

我们先做几次提交,把仓库历史变成下图左边那样:

执行命令git rebase -i HEAD~3(【-i】参数是指互动模式,即可以自己在Vim中编辑reabse的模式)来准备合并最新的三条记录。这时会进入Vim界面,用于写入真正的合并操作,就像上图中部那样<操作符> <版本ID> <该版本的Commit Message>。其中,操作符的缩写及意义如下表:

操作符 意义
p 使用本次提交作为这个几个合并的新基
r 使用本次提交作为这个几个合并的新基,但重新编辑提交信息(commit message)
e 使用本次提交作为这个几个合并的新基,但不进行修正(即产生一个新的版本ID号)
s 将本次提交合并到上一个基(从下往上看,参考上图的中图)
f 类似s操作,但是把它们的提交信息全部放弃
x 使用Shell运行接下来几行的命令(一般用于高级操作,属于大佬秀操作的专属操作符)
d 直接移除该提交

最终的rebase效果就如同上图的右图一样。整个流程就像下面这样:

② 多分支变基git合并

rebase的另外一种操作场景,就是用于分支合并时的历史整理。 当你的项目越来越大,你的仓库历史会出现越来越的的合并操作:

这就非常让人感到困惑,往往搞不清版本是怎么向前推进的。如果能把master这条线捋直该多好!

这时候,git rebase就又派上用场了。

练习

  1. 新建一个库,新建一个test.txt文件,键入内容【master 1】,提交。
  2. 创建分支feature_1,修改test.txt文件,改为内容【feature_1 1】,提交。
  3. 新建一个文件feature_add.txt,提交。
  4. git checkout master,修改text.txt内容为【master 2】,提交。
  5. 新建一个文件master_add.txt,提交。此时你的仓库历史应该如下图左侧所示。
  6. git checkout feature_1,执行git rebase master,解决冲突,然后执行git rebase --continue完成变基操作。观察工作区内容。此时你的仓库历史应该如下图中侧所示。
  7. 使用git checkout master,然后向前checkout该分支的版本。此时你的仓库历史应该如下图右侧所示。

你的仓库历史应该会是这样:

整个流程可以用下图所示的样子进行总结:

更干净的merge

这里会用到两条指令:

  • git merge --sqush 压缩合并,把要并入的分支上的所有历史并为一个,但可能会丢失部分提交信息(除非在commit message中写了Sign off信息)
  • git merge --rebase 变基合并,保留了所有信息,但把所有的历史接到了base的分支上,就像我们上面利用git rebase合并两个分支一样。

下一章中,我们会提到什么是pull request,到时候你将看到下面这张图:

你会看到这三种合并请求分支(pull request branch)的方式,当你明白你在做什么时,推荐使用git merge --rebase来并入这些pull request的请求。 但如果你实在拿不定主意,采用”完整合并”总不会是太差的选择。


返回目录