使用 Git 时,我的工作流程通常包括启动 TortoiseGit 并选择我想要提交的文件。
这(我假设)运行git add (?) 并将这些更改提交到本地 repo。
我的问题是——为什么将文件添加到索引和提交它们之间需要分开?
是否有任何用例可以简单地将文件添加到索引而不同时提交它们?
使用 Git 时,我的工作流程通常包括启动 TortoiseGit 并选择我想要提交的文件。
这(我假设)运行git add (?) 并将这些更改提交到本地 repo。
我的问题是——为什么将文件添加到索引和提交它们之间需要分开?
是否有任何用例可以简单地将文件添加到索引而不同时提交它们?
将文件添加到索引称为暂存。暂存提供了将要提交的内容和要保留在提交之外的内容之间的分离。如果您进行了一些更适合不同提交的更改,则可以将它们保留在那里而不进行暂存,并对添加到索引中的内容进行提交。
因此,从本质上讲,它可以帮助您准备简单、连贯的提交。
我经常使用索引/暂存区。它可以被认为有点像购物车。它可以让你在你的项目中四处游荡,随手添加东西,装满你的购物车。一旦你拥有了你想要的东西,你就提交(即购买这些更改并离开商店)。
其中一个很棒的功能是补丁添加。git add -p
akagit add --patch
允许您从文件中选择特定的块,因此您实际上可以提交各种文件的部分。尽管我使用 Vim 的病原体插件,但我每天都这样做,这使得从更改到更改,在工作副本和索引副本之间来回移动它们变得非常容易和直观。一旦我只将一个不错的、细粒度的提交的部分添加到购物车中,我就会使用一个明智的、细粒度的提交消息(50 个字符或更少)来提交它。这让我的历史变得难以置信,它让我在一小时后改变主意,并以交互方式 rebase 将提交推送到一起,并将它们重新排序为更合理的流程,有时让单元测试在每次提交时工作,所以我有在我的历史上到处都是干净、安全、回滚点。
我还使用补丁添加来帮助我确定文件的哪些部分一起有意义。在 Vim I do,gs
中,会在新的拆分窗口中弹出打开当前文件 repo 的 git 状态。我使用<C-n>
和<C-p>
跳过带有实际文件的状态消息行。我D
在这些行上使用在一组拆分窗口中对它们进行 vimdiff,然后]c
从c[
更改到更改的顶部跳跃,使用dp
(diff put) 和do
(diff gain) 将更改移入或移出当前缓冲区(这些工作来自任何一个拆分,并在缓冲区<C-w>h
之间<C-w>l
来回跳跃)。一旦我喜欢我为该文件准备的内容,我:w
就会保存它,然后<C-w>k
再次到状态拆分以选择一个新文件以这种方式-
暂存,或者在任一组中的文件上将它们完全切换到暂存和退出暂存,或者cc
实际提交,然后它会要求提交消息。在提交之前,我可以通过这些方式回顾所有的事情,而且我经常会意识到我忘记了一些东西,或者添加了一些我不应该的东西,然后更正它。因此,我的提交相当原始。如果我愿意commit --amend
,我可以暂存并使用,cA
而不是cc
,或者ca
如果我还想改写提交消息。
简而言之,提交整个文件——就像我过去在 SVN 时代所做的那样——现在对我来说感觉非常粗糙和不正确。在工作时只改变一个问题真的很难,但是通过索引的力量添加补丁让我梳理出在一次提交中有意义的实际更改。
暂存几乎就像文件的迷你提交。您可以在实际提交之前暂存、重新暂存、查看更改,甚至恢复到最近的阶段。做几个小提交可以帮助你组织,就像做几个完整的提交一样。
本质上,这是一个更精细的粒度级别。
此外,它还可以让您在提交之前在本地进行一些操作 - 它实际上与创建一个游乐场分支并执行一堆提交,然后在最终提交之前合并回来。只是比所有这些都轻得多。
您不必提交添加到索引/暂存区域的所有文件。
git add fileA
git add fileB
git add fileC
用例 1:仅提交 fileA 和 fileB:
git commit -m "fileA, fileB added." fileA fileB
用例 2:将文件添加到暂存区域后跟踪文件的更改。这将向您显示工作副本与上次将文件添加到暂存区域之间的区别。
在 SmartGit 中,您可以在文件上单击鼠标右键,然后选择 satge。