我真的相信在一个问题上有一个提交是一个好习惯。我确定我在“最佳实践”这样的文章中的某处读过它。
因此,我的工作流程如下:
git checkout -b new-issue
创建了一个新的本地分支。squash
提交,rebase
他们进入当前主题分支。git revert
提交,找到错误,修复错误,并将新补丁提交到专题分支。我不会更改远程存储库的历史记录。但是今天,我听到以下工作流程后感到很惊讶:
merge --no-ff
将问题分支与专题分支合并(因此我们将{merge}提交“revert
。”git bisect
来查找错误。根据第一种方法,我们将有一个干净的git历史记录,并且不知道在开发过程中使用的开销分支。
根据第二种方法,我们将有一个非常混乱的历史,有很多丑陋,不必要的合并和提交只有一个问题。但是,我们可以使用git bisect
来查找错误。 (也许这对于重构更好?)
您对这两种方法有什么利弊?
您使用哪种方法?为什么?
在实践中,您是否真的使用git bisect
来查找错误? (我没有...)
答案 0 :(得分:7)
第二种方法不必有很多丑陋和不必要的合并和提交。这是我喜欢做的事情:
--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)
上图与方法#1具有相同的优点:
您可以使用--first-parent
参数git log
获得一个简洁的摘要,类似于您使用方法#1获得的内容:
* 354b644 Merge branch 'topic3'
* db13612 Merge branch 'topic2'
* a5b6b16 Merge branch 'topic1'
... (more history not shown)
git diff 354b644^..354b644
将显示主题#3的更改内容。但是你得到的好处是方法#1无法给你:
b45fbcf
和7dfc7e5
(针对topic3
分支)引入了大量噪音,但没有实际的逻辑更改。有人试图回答这个问题,“对主题#3做了哪些逻辑修改?”如果把所有这些提交都压成一个,那么可能很难深入挖掘噪音。我可以想到一个缺点:可能很难将软件开发工具配置为仅遵循第一父路径并忽略所有这些中间提交。例如,there is no --first-parent
argument to git bisect
。另外,我对Jenkins不太熟悉,知道将它配置为优先构建和测试所有其他提交的第一个父路径是多么容易。
答案 1 :(得分:5)
最后,它主要是个人品味问题......只能解释我的品味(并为其提供一些理由)。
我倾向于保持个人提交,即使他们只是“修复愚蠢的拼写错误”。任何“历史重写”都会创建前所未有的提交,因此保证永远不会被测试。此外,最小的提交会使git bisect
在以后出现错误时非常有用。最好能够将其缩小到一些变化的线,而不是一周的工作,压扁在一起。
如果一个开发分支得到了一个混乱的历史,我清理它(最低限度,即,恢复提交从未发生过,一般修复,如空格或变量重命名可能早先应用,一些重新排序将相关的变化放在一起)。提交仍然很小,很少被压扁。这种清理我主要是逐步完成的。然后我将清理过的分支与“官方”分支合并(或变基)。