git的两阶段提交过程(登台)有什么好处?


174

我正在学习git,我注意到它有两步提交过程:

  1. git add <files>
  2. git commit

第一步是将修订内容放入所谓的“临时区域”或“索引”。

我感兴趣的是为什么要做出此设计决定,其好处是什么?

另外,作为git用户,您可以这样做还是只使用git commit -a

我问这个问题,因为我来自不具备此功能的bzr(集市)。


3
+1询问。我使用Tortoise SVN,它具有相同的方法,但我从来不明白为什么。
DPD

3
暂存区并不稀奇。例如,TFS中的等效项将是在签入之前选中或取消选中文件旁边的框。仅提交已选中的文件。与Git的区别在于,如果使用git add -p,可以选择提交一个文件,而不选择提交同一文件的另一文件
Kyralessa

我发现此链接总结了此处回答的大部分内容,并添加了更多用例以证明需要进行升级。
Veverke

2
这个问题实际上已经回答了,但这里也是一个很好的解释:stackoverflow.com/questions/4878358/...
guitar_freak

1
不要忘记 git status并且可能git push。对于有关git的所有宣传,(以及GitHub共享代码都很棒),这些部分非常令人讨厌
user949300

Answers:


83

将工作分成单独的提交。您可能已经多次打开文件来编写单行修复程序,但是同时您发现格式错误,可以改进某些文档或其他一些不相关的修复程序。使用其他RCS时,您必须将其记录下来或提交给内存,完成所需的修复,提交,然后返回以修复其他内容(或使用不相关的内容创建球状提交) 。使用Git,您只需一次修复所有问题,然后使用git add -i或分别执行阶段并提交单行git-gui

不要破坏构建。您正在进行复杂的修改。因此,您尝试不同的方法,其中一些方法比其他方法更好,而某些方法则使事情变得更糟。使用Git,您可以在修改使情况变得更好时进行发布,而checkout在修改不起作用时(或进行更多调整)进行登台。您将不必依靠编辑器的撤消功能,您可以checkout使用整个存储库,而不仅仅是逐个文件,以及任何文件级错误(例如,删除未提交的文件或在文件保存后关闭+关闭)错误的修改)不会导致大量工作丢失。


3
来自不具有此功能的DVCS(bzr),这听起来很像我目前通过自由使用编辑器的“撤消”缓冲区,“还原<file>”命令和选择性提交(“提交<file>“)。听起来像git的这个功能有可能变得更有条理。
thomasrutter 2011年

1
关于“其他RCS”,不一定是正确的。实际上,您可以使用patch在Mercurial中实现相同的功能。
Lucio Paiva 2014年

1
@ l0b0,关于您的第二点。如果只有一个阶段提交,则可以将更改(与git add一起使用)直接作为提交提交。如果发现做错了什么,那您将删除该提交,然后回到进行提交之前的状态。使用分段概念,您不只是这样做,而是增加了更多的复杂性吗?
alpha_989 '18

到目前为止,您的第一点很有意义,尽管我还没有使用过。从理论上讲,为什么不能通过git add -i单阶段提交来执行类似a的操作?您只需选择与单个功能相关的一堆文件(或文件中的行),然后进行提交即可。然后,你会回来,并做了第二次提交相关的另一个特征..
alpha_989

@thomasrutter,从您的陈述看来,您似乎建议暂存区创建“手动撤消点”。在具有永久撤消功能的VIM中,您可以非常可靠地获得无限的历史记录。这也会以一种git-branch类型的方式自动跟踪(jovicailic.org/2017/04/vim-persistent-undo)。此外,每当您进入正常模式时,您的撤消历史记录都会被自动跟踪。因此,它减轻了您必须创建“手动撤消点”的精神负担。为什么使用编辑器的“撤消”缓冲区不那么有条理?
alpha_989 '18

65

对我来说,好处之一是能够逐步“添加”文件。在提交之前,我会检查每个文件。审核文件后,我将其添加。当我git status或时git diff,git仅向我显示已修改但尚未添加的文件。查看完所有文件并添加它们后,即可提交。

是的,我发现登台区域非常有用。

不,我从不使用git commit -a。但是,我经常使用git add -u。这样,我仍然可以可视化要提交的内容。


2
究竟。优点是您可以精确地控制正在上菜的食物。
乔什(Josh K)

多次暂存一个文件时会发生什么?是否会在登台区域“合并”?
m4l490n

21

好处很简单:它使您可以完全控制何时要提交的文件。对于这个问题,您可以使用git add -p来控制哪些要提交。


2
我一直想知道如何做到这一点。我希望有一个文件,.gitignorelines以便您可以对单个行进行本地更改,以使提交可以保留并保持完整。
亚历克斯·格雷

3
@ReinHenrichs,考虑需要由每个开发人员更改的配置文件。
2014年

1
@Ian因此,文件的一部分很少更改并且可以共享,而文件的一部分经常以不兼容的方式更改,并且不会共享?支持这种虚假的行为肯定听起来像是一种反特征。
Rein Henrichs 2014年

1
@ReinHenrichs,是的,当文件包含数据库服务器的名称并且每个开发人员都有自己的数据库时,这很常见。
2014年

4
@Ian您的问题确实在那里,您有一个应该是应用程序的配置文件,还包含一些机器/设备特定的配置。我所知道的所有配置系统都可以将其拆分为多个文件。因此,例如,您拥有app.conf包含要共享的内容的,然后将db.conf其放入.gitignore列表中。问题解决了。如果您使用的是专有产品,则应该真正考虑在其中获得如此简单的功能。或在预处理事件中将其置于预处理器中。那里有很多解决方案。
Aidiakapi 2015年

1

我喜欢的好处之一是能够提交更改的一部分。即,通过使用git add -e。我提交的频率不如我有时候所需的那么频繁,而git add -e命令可以使我对更改进行一定程度的解释。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.