我应该选择git merge还是git merge --squash?

3

我一直在反复考虑,无法确定哪种工作流程更好。我应该优先选择将合并到主分支的分支压缩吗?还是只是将它们合并。

我倾向于使用合并-压缩,并一直保持一致。

合并-压缩的优点:

  1. 更清晰的历史记录。
  2. 更容易使用二分查找。

有没有任何理由我不应该使用合并-压缩,而改用普通的合并呢?

2个回答

4

这要看情况。

压缩合并会丢失信息,是否需要压缩取决于这些信息是否重要。对于在未来六个月或六年后试图弄清楚为什么一行代码是这样的人来说,这些信息是否重要就很重要了。这取决于分支中有什么、更改的数量、更改的大小以及日志消息的好坏。

一个简单的经验法则?考虑压缩的结果,并问自己“如果我在主分支上编码,我会提交这个吗?”如果答案是肯定的,那么diff和日志结合起来将允许未来的人弄清楚为什么一行代码发生了变化,那么就压缩合并。

如果答案是否定的,这不是一个可以接受的提交到主分支的提交,更改太多或者太多交织的更改,那么就不要压缩它。合并它,也许在考虑分支内的任何提交是否可以一起压缩之后再合并它。

至于压缩合并是否“更干净”、“更容易二分”...我觉得这只是表面上的。如果你把书架上所有书的页面拿出来,缝成一个巨大的封面,那么这样做就“更干净”了,因为现在你只需要担心一本书。如果它们是一堆各自独立的小说,那么这并没有什么帮助。如果它们是年度会议报告,最好将它们绑在一起。

从某种意义上说,压缩合并更容易二分,因为你不太可能有一个提交会破坏构建,但是如果你的二分落在一个巨大的更改块上,你仍然必须解决大量可能导致问题的情况,这使得二分者的工作更加困难。

使用相同的标准来决定是否压缩合并,就像你用于提交到主分支一样,你会做得很好。


2
我喜欢你的推理,我认为它提供了一种实用的方法。 - anio
我认为最大的缺点是你失去了提交者,因为在合并之前你自己做了“最后”一次提交。如果你是独自工作,那么这没问题,但是在团队中工作时,最相关的信息之一是谁实际上完成了工作/功能。 - Tipi

3
快进合并在想保留所有期间提交时非常有用,例如在分支上尝试可能无效的东西。丢弃临时分支比重置工作分支更容易。当实验成功时,将提交向前快进到工作分支上,使其保持原样,就像实验一直在上面一样。
我不知道为什么不把工作提交压缩成一个全面的提交,并使用涵盖所有更改的消息。正如您所指出的那样,这可以使历史记录保持清晰,并更加易于处理。根据我的观察,它是保持树形结构整洁的首选方法。 git merge --squash 创建一个父提交,因此不显示与正在合并的父提交的连接。
-A---------C  <-- `git merge --squash`
  \
   *--*--B

另一个选项是使用git merge --no-ff(不快进)来强制进行合并提交。此提交将具有两个父级。优点在于保持树的清晰,同时仍然具有详细的提交历史记录(如果需要)。
-A---------C  <-- `git merge --no-ff`
  \       /
   *--*--B

两个 C 提交是相同的,如果要保留 B,请选择后者。


Git合并相邻的两个分支时,如果所有原始提交记录均可用,那么使用这种方式不是更容易吗?这样冲突的概率会更低。 - Stijn
并不完全是这样。提交是一组更改,因此所有原始提交加在一起就是一个更大的更改集。单个合并提交(最坏情况下)与所有原始提交相同。如果在完整列表中有更改或反转先前提交的提交,则合并提交将被展平。在这种情况下,合并提交是比完整提交集中的更改少的更改集--需要做的工作更少。无论如何,最终结果都是相同的更改集--因此任何合并冲突都会发生。 - David Culp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接