你在开发过程当中使用Git Rebase仍是Git Merge?

摘要:在git里面常常的一个争论是到底用rebase仍是用merge?

1. 痛苦吗?代码历史中的迷失羔羊

咱们先来看一个真实的代码提交历史图形化截图:git

图片源自 https://storage.kraken.io/kk8yWPxzXVfBD3654oMN/c8b97f4dbb5f7d49fc3eb3624eafff79/london-tube-map-commit.png程序员

 

https://dev.to/neshaz/git-merge-vs-git-rebase-5134github

 

不知道你们看到这张图之后有什么感觉?是否是很无语呢?我是无语凝噎的感觉。代码历史到了这个地步,基本上是废了的!!!安全

经过本文咱们就来谈一下代码历史线的问题。这里涉及到一个代码历史的管理问题,若是你但愿拥有比较清晰的代码历史,从而能够很快速地追溯你之前的代码记录的话,你必定要关注这个话题。工具

若是你做为一个程序员用过mercurial,你可能对这个rebase概念已经有所了解。目前程序员用的最多的source control工具是git。在git里面常常的一个争论是到底用rebase仍是用merge?url

说争论其实是不太准确的。由于在实际工做中,这主要有两种状况,一是根本就不知道rebase,另一种是根本就不知道怎么用rebase。spa

那咱们就说一下rebase和merge的区别,在功能上rebase把你当前的修改工做提高到最前沿,
你本身独有的修改记录顺序不会改变,可是时间主要会基于当前目标分支的时间戳进行调整。.net

Merge不会改变时间戳。这样就会致使不一样的人在合并本身修改代码记录的时候,会出现相互交错的情形。本文开篇是一张代码提交历史的截屏,里面的连线就像电路板同样复杂。翻译

出现这样的状况,主要是由于程序员不作rebase直接merge形成的。指针

而相似这样电路板状的代码提交历史是没有意义的,由于太过复杂了。几乎没有可读性。若是你想去查看某些历史记录的时候,很容易被迅速淹没在这些信息海洋里面没法自拔,最后失去自我,迷失了。

2. Git Merge vs. Rebase

小注:虽然已经参考连接中标注,可是有必要再强调一下此节翻译参考了以下连接的英文内容:

 

https://dev.to/neshaz/git-merge-vs-git-rebase-5134

 

Git merge 和rebase的目的是同样的,它们都是将多个分支合并成一个。虽然他们最终的目标是同样的,但这两种方法实现的方式是不一样的。那么咱们应该用哪一个呢?

这里咱们有一个示例仓库,它有两个不一样的分支:主分支和特性分支。咱们想把它们融合在一块儿。让咱们来看看如何使用这些方法来解决这个问题。


图片源自 https://storage.kraken.io/kk8yWPxzXVfBD3654oMN/fc73a41ce658a6a566e2a54d60534ade/git-flow.png

 

https://dev.to/neshaz/git-merge-vs-git-rebase-5134

 

Merge

当你运行 git merge 时,你的 HEAD 分支会生成一个新的提交,并保留每一个提交历史的祖先。

 

图片源自 https://storage.kraken.io/kk8yWPxzXVfBD3654oMN/673b91456bdc6fd454c5ad203f825568/git-merge-2.png

https://dev.to/neshaz/git-merge-vs-git-rebase-5134


Fast forward merge是一种不建立提交的合并类型,会更新分支指针到上一次提交。

Rebase

Rebase是将一个分支的修改重写到另外一个分支上,而不须要建立新的提交。

你在特性分支上的每个提交,都会在主分支上建立一个新的提交。这看起来就像这些提交一直是写在主分支之上的同样。

图片源自 https://storage.kraken.io/kk8yWPxzXVfBD3654oMN/5ade4f7276bc6ad18dad4b6078950ac9/git-rebase.png

https://dev.to/neshaz/git-merge-vs-git-rebase-5134

 

Merge的优势和缺点

优势

  • 使用简单,易于理解。
  • 保持源分支的原始上下文。
  • 源分支上的提交与其余分支的提交是分开的。
  • 能够保留提交历史。

缺点

图片源自 https://storage.kraken.io/kk8yWPxzXVfBD3654oMN/c8b97f4dbb5f7d49fc3eb3624eafff79/london-tube-map-commit.png

https://dev.to/neshaz/git-merge-vs-git-rebase-5134

 

Rebase的优势和缺点

优势

  • 代码历史是简化的、线性的、可读的。
  • 与许多独立的特性分支的提交历史相比,操做单个提交历史更容易。
  • 干净、清晰的提交信息能够更好地跟踪一个bug或什么时候引入的某个功能。能够避免众多的单行提交污染历史。

缺点

  • 会更改历史提交时间,可能会丢失上下文。

比起Merge,你须要更加当心的使用Rebase。

应该用Merge仍是Rebase?

当你的团队对于rebase不熟悉时,那么git merge就是你的正确选择。

  • Merge容许保存任何给定功能的提交历史,而没必要担忧覆盖提交和改变历史。
  • 它能够避免没必要要的 git revert或reset。

另外一方面,若是你更看重干净、线性的代码历史,那么git rebase是最合适的。这种方式能够避免没必要要的提交,并保持更集中和线性的变化!

这里要注意的是,若是你不正确地重写了历史,可能会致使严重的问题,因此在使用Rebase时请确保知道你在作什么。

3. 一杯水与一桶水

先说一下一杯水和一桶水的关系,这个关系能够用来描述老师向学生传授知识的情形。主要意思是说老师要是给学生一杯水的话,这个老师必需要有一桶水才行。

其实对于咱们软件行业来讲,这个道理也是适用的。

关于本文的聚焦点代码历史,咱们想给外部呈现的是清晰干净的代码历史记录。要到的这个目标,咱们须要作不少的工做,这项工做相较于干净的代码历史就是一桶水与一杯水的关系。

这也是咱们常常说的,对本身狠一点,让别人舒服一点。对本身狠一点不是一句空话,其实是让本身绞尽脑汁的去想,如何把这个事情作好?把本身放在对方的角度上去看咱们的输出结果。咱们问本身,我做为这些代码的维护者和接收者,是否是能够接受这样混乱的代码历史记录,答案固然是否认的。

明白了这一点,在咱们作代码历史管理的时候,再苦再累也是值得的。

一些有多年工做经验的程序员,他们可能用过不少代码管理的工具,这些代码管理工具在使用的时候常常用的一个操做就是merge。进入到git时代之后,这些程序员也保留了这样的习惯,直接就merge。

我跟一些程序员聊过,他们甚至都没有意识到有rebase这个操做。有的则以为rebase太麻烦了,用了几回就放弃了。

这绝对是人之常情。

当咱们习惯了用一种方式作事的时候,咱们作得越久感受越安全,由于它是行之有效的,可以解决问题的。当有另一种更好的方式,可是却与之前的方式有很大差别的时候,咱们就会有本能的排斥心理。这是源于咱们对未知领域的一种恐惧感。

离开温馨区之后,咱们大多数人都会有一种不适应,有的甚至会产生很强烈的失落感。

可是当咱们回归本心的时候,咱们会发现咱们所付出的一切,经受的痛苦都是值得的。由于咱们的初心就是让用户满意。代码历史的用户就是咱们这些程序员。

4. 如何正确作rebase?

要点备注:

Rebase相关的要点有这几个:

  1. 在本身的分支上作Rebase;
  2. 要Rebase正确的目标分支,注意这个目标分支不是你的远程分支,这个地方常常有人犯错;
  3. Rebase要常作,以免出现冲突,或者冲突的难度增长;
  4. 在合入代码以前,必定要最后作一次Rebase再Merge;
  5. 最好用Squash Merge, 添加正确的提交消息;
  6. 不要在主分支上作Rebase;
  7. 尽可能不要force push;

在主分支上应该rebase吗? 怎么去作rebase?

首先,我要强调一下,在主分支上不要作rebase。这是由于若是你在主分支上作了rebase,若是你是第1次push可能没有问题,可是若是别的人也作了一个rebase,这个时候就致使你的主分支上有两个不一样的head,这个时候若是想再push的话就存在问题了。

若是一切可控的话,你能够很是粗暴的使用强制push。可是若是团队成员比较多,会致使这样的操做会冲掉其余已经进来的提交。

除非万不得已,咱们坚定不能在主分支上去作rebase。

接下来讲一个正确使用rebase的场景。在接到一个任务之后,咱们会在主分支上最新的节点处提交上建立一个新的分支。在新的分支上,咱们会不断的进行新的提交,直到完成这个分支任务。

到这个时候,咱们想建立一个merge request或者pull request,在此以前,咱们首先要作的就是rebase,rebase选的目标分支是咱们的主分支。

完成此次rebase操做之后,咱们就能够建立mr或者pr了。在审查过程当中可能有不少修改意见,修改完成之后须要先
rebase再push。如此反复几回,mr或者pr审批经过。此时要作一次squash merge把数次提交打包合成一个到主分支上。

以上是我对在正常工做流程中如何使用rebase进行了一个现实案例的描述讲解,但愿你们去体验一下,告诉我体会,请留言说说你的想法。

参考文献

 

 

https://dev.to/neshaz/git-merge-vs-git-rebase-5134

https://www.perforce.com/blog/vcs/git-rebase-vs-merge-which-better

https://product.hubspot.com/blog/git-and-github-tutorial-for-beginners

https://git-scm.com/docs/gittutorial

 

 

 

点击关注,第一时间了解华为云新鲜技术~

相关文章
相关标签/搜索