[转载]Git commits历史是如何做到如此清爽的?

[转载]Git commits历史是如何做到如此清爽的?

https://www.zhihu.com/question/61283395

Question

今天在看vue源码时随手看了一下commit历史,然后就被震惊了。请问这是怎么做到的?怎样的git实践才能做到这么清爽?

preview

Answer

作者:elgoog
链接:https://www.zhihu.com/question/61283395/answer/186223235
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Vue作者已经放出了权威答案,我也在这补充一下自己平时的git workflow。在开发一个feature或者修个bug的时候,一般都会在最终要merge进的分支上开个新的分支,所有的工作都commit到这个新的分支上。feature写完或者bug修完,在要merge之前,rebase新分支到最后要merge的分支上,这相当于把你在新分支上的所有新commit依次cherry pick到要merge的分支的最新commit后面,这样后续的merge就一定会是一个非常爽的fast forward。而且在rebase的同时可以进行squash,把逻辑上相似的commit都塞到一个commit里面,然后给他一个描述性比较强的commit message。这套操作下来之后commit历史会非常清晰一目了然,看某些同事的项目的commit历史里面各种save, save work, fix bug, fix bug again的确是一种煎熬,好的commit应该反映出一个项目是怎么一步步开发下来的,是软件开发的航海日志,黑匣子,任何码农都应该建立良好的commit习惯。

Linus曾经在Linux的某个pr下面讨论了好的commit应该长啥样,非常有启发: Add support for AR5BBU22 [0489:e03c] by WNeZRoS · Pull Request #17 · torvalds/linux


作者:灵剑
链接:https://www.zhihu.com/question/61283395/answer/233700381
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

rebase是很好的工具,不过我其实反对合进master分支的时候做rebase或者fast-forward,我喜欢的方式是

  1. 待合并的分支rebase到master
  2. master merge待合并的分支(禁用fast-forward)

这样最大的好处是能清楚看到每次merge到master分支的界限在哪里,万一出问题了,可以把整个merge都revert掉。最后的graph上大体是每次分出来一个branch然后马上合回来的形状,也没有比一条单链差很多。另外,merge的commit自己可以有message,如果发生了conflict也可以记录下来。

当然如果这次合并的branch一共只有一个commit那么直接fast-forward也没有什么不可以的。

反对滥用amend和squash(以及soft reset),这才是爱慕虚荣的表现,除了引入莫名其妙的conflict以外没有任何积极意义。保留每次提交的细粒度历史版本对于合并、回滚是非常重要的。比如说开发完成了一个新功能,突然发现其中对某个文件的某步修改是错误的,需要撤销,如果已经squash了那就难找了,可能这个文件被前后修改过很多遍,很难分离出来某一批次的修改了。再比如说cherry-pick,可能master分支上发现了一个重大的bug,这个commit需要cherry-pick到各个版本分支和开发分支上,如果这个cherry-pick以后被squash掉了,再合并的时候就会出现conflict。仅仅当很少的情况,比如这个commit仅仅是修复上个commit中的提交错误或低级失误的时候,用amend和squash有一定意义(去掉一堆无意义的bugfix提交)

RobertLiang

A post-graduate in USTC.

You must be logged in to post a comment