什么git提交练习更好?

Via*_*iuk 9 git merge commit rebase bisect

我真的相信在一个问题上有一个提交是一个好习惯.我确定我在"最佳实践"这样的文章中的某处读过它.

因此,我的工作流程如下:

  • 对于一个新问题,我创建了一个新的本地分支git checkout -b new-issue.
  • 将所有更改提交到其中.有时这涉及很多提交.
  • 完成后,我squash提交并将rebase它们转换为当前的主题分支.
  • 如果出现问题,我可以git revert提交,找到错误,修复它,并将新补丁提交到专题分支.我不会更改远程存储库的历史记录.

但今天,我听到以下工作流程后感到很惊讶:

  • 为新问题创建新分支.
  • 承诺一切.
  • 使用merge --no-ff合并与专题分支问题分支(所以我们必须"合并提交",我们可以revert).
  • 如果出现问题,我们可以git bisect用来查找错误.

根据第一种方法,我们将有一个干净的git历史,并且不知道在开发过程中使用的开销分支.

根据第二种方法,我们将有一个非常混乱的历史,有很多丑陋,不必要的合并和承诺只有一个问题.但是,我们可以git bisect用来查找错误.(也许这对于重构更好?)


  • 您对这两种方法有什么利弊?

  • 你使用哪种方法,为什么?

  • 在实践中,你真的习惯git bisect了找虫子吗?(我还没......)

Ric*_*sen 7

第二种方法不必有很多丑陋和不必要的合并和提交.这是我喜欢做的事情:

  1. 创建一个新的主题分支
  2. 做一堆提交
  3. 在合并回父分支之前,清理提交:
    • rebase到最新版本的父分支
    • 壁球错字修复提交
    • split commit一次做多个事情进入单独的提交
    • 重新排序提交,以便审阅者更容易理解更改的顺序
    • 等等
  4. 合并--no-ff到父分支

上述步骤会产生如下历史记录:

*   354b644 Merge branch 'topic3'
|\
| * 54527e0 remove foo now that it is no longer used
| * 1ef3dad stop linking against foo
| * 7dfc7e5 wrap lines longer than 80 characters, no other changes
| * b45fbcf delete end-of-line whitespace, fix indendataion
|/
*   db13612 Merge branch 'topic2'
|\
| * 961eebf unbreak build by adding a missing semicolon
|/
*   a5b6b16 Merge branch 'topic1'
|\
... (more history not shown)
Run Code Online (Sandbox Code Playgroud)

上图与方法#1具有相同的优点:

  • 您可以使用--first-parent参数来git log获得类似于方法#1所获得的简明摘要:

    * 354b644 Merge branch 'topic3'
    * db13612 Merge branch 'topic2'
    * a5b6b16 Merge branch 'topic1'
    ... (more history not shown)
    
    Run Code Online (Sandbox Code Playgroud)
  • 您仍然可以轻松检查主题分支中所做的全部更改.例如,git diff 354b644^..354b644将显示主题#3的更改内容.

但是你得到的好处是方法#1无法给你:

  • 历史记录容易审查:提交b45fbcf7dfc7e5(对于topic3分支)引入了很多噪声但没有实际的逻辑变化.有人试图回答这个问题,"对主题#3做了哪些逻辑修改?" 如果所有这些提交都被压缩成一个,那么可能很难深入挖掘噪音.
  • 合并提交很好地识别合并分支上的一系列提交的上下文(例如,这组提交是为了解决主题#3).
  • 更精细的提交粒度使得更容易弄清楚为什么进行了特定的更改,这可以帮助区分意外变化和有意 - 但微妙.
  • 如果多个人在分支机构上进行合作,您可以看到他们是谁以及每个人贡献了多少.
  • 合并主题分支上的提交数量可让您大致了解已更改的内容.
  • 提交的时间范围可以提供有用的上下文.
  • 您可以轻松地挑选在不同分支上进行的特定更改(例如,樱桃选择将错误修复到发布分支所需的最小更改).

我可以想到一个缺点:可能很难将软件开发工具配置为仅遵循第一父路径并忽略所有这些中间提交.例如,没有--first-parent争论git bisect.另外,我对Jenkins不太熟悉,知道将它配置为优先构建和测试所有其他提交的第一个父路径是多么容易.


von*_*and 5

最后,它主要是个人品味问题......只能解释我的品味(并给它一点理由).

我倾向于保持个人提交,即使他们只是"修复哑巴错别字".任何"历史重写"都会创建前所未有的提交,因此保证永远不会被测试.此外,git bisect当bug稍后浮出水面时,最小的提交会非常有用.最好能够将其缩小到几个变化的线,而不是一周的工作,压扁在一起.

如果一个开发分支得到了一个混乱的历史,我清理它(最低限度,即,恢复提交从未发生过,一般修复,如空格或变量重命名可能会提前应用,一些重新排序将相关的更改放在一起).提交仍然很小,很少被压扁.这种清理我主要是逐步完成的.然后我将清理过的分支与"官方"分支合并(或变基).