据我所知,典型的Git工作流程分为三个步骤:(修改工作树中的文件) - > (使用git add/rm/etc
修改索引) - > (运行git commit
)。
但是,为什么Git不将工作树视为临时区域?例如,你修改一个文件,它会自动“暂存”进行提交,除非你特意告诉git不要暂存它。这更像是一种“选择退出”的方法,而不是“选择加入”,这对我来说很有意义,因为工作树中99%的文件都将被提交。它还会使整个git stash
机制变得多余,因为您可以简单地从工作树创建一个临时分支,而不是save
以后隐藏apply
。
如果工作树和索引之间存在分离的正当理由,我很乐意听到它...也许我的困惑源于我还没有完全理解Git的事实
答案 0 :(得分:4)
Git网站实际上有一个good explanation的暂存区域,它存在的原因,它提供的好处,以及在提交时绕过它的方法。
取自http://git-scm.com/about/staging-area
临时区域
与其他系统不同,Git有一种称为“临时区域”或“索引”的东西。这是一个中间区域,可以在完成提交之前格式化和审查提交。
将Git与其他工具区分开来的一件事是,可以快速暂存一些文件并提交它们,而无需在工作目录中提交所有其他修改过的文件,或者在提交期间必须在命令行上列出它们
这允许您仅暂存已修改文件的某些部分。在您意识到忘记提交其中一个之前,对文件进行两个逻辑上无关的修改的日子已经一去不复返了。现在,您可以暂停当前提交所需的更改,并为下一次提交暂存另一个更改。此功能可根据需要扩展到文件的多个不同更改。
当然,如果您不想进行这种控制,Git也可以轻松忽略此功能 - 只需在您的提交命令中添加'-a',以便将所有文件的所有更改添加到暂存区域
希望这会有所帮助。干杯!
答案 1 :(得分:2)
Mercurial基本上是“没有索引的git”,因此证明可以完成。任何“为什么”的问题都属于很多灰色地带。但这就是索引提供的内容:
非常快“git commit”:索引已包含下一个提交;它只需要重新格式化为树对象和最终提交对象。
暂存区域,以便您可以使提交与工作目录不匹配。 (并非所有人都认为这是一件好事。)在Mercurial中,要在省略A
的工作版本的同时提交文件C
和B
,您必须发出一个名为所有要包含(或排除)的文件一次拼写出来。在git中,您可以设置一个阶段,运行git diff --cached
(或--staged
),确定是否正确或需要调整,git add
或git reset
来调整阶段,运行另一个git diff --cached
,等等。 (在Mercurial中,我发现通过将所有“不需要的”更改移出存储库区域hg commit
,最简单的方法来实现同样的目的,然后将这些更改移回。)
易于修改未发布的提交。习惯于在git中使用暂存区域和修改进程,当我在Mercurial中进行修改时,我惊讶地发现我的整个当前工作树成为新修改的提交。 (我不应该感到惊讶,但我是这样!再次回到不同的哲学:在hg中,你完全将“尚未准备好”的部分从回购中移出,以免它们潜入。)
< / LI>棘手的黑客攻击。 (同样,不是每个人都认为这是一件好事。)特别是你可以在索引中设置比特,如“假设未改变”或“意图添加”,这会影响未来的提交(再次因为索引在某种意义上说,“正在构建的下一个提交“)。
当发生合并冲突时,一种保持并因此轻松访问正在合并的文件的方法。
最后一个值得一些额外的解释。假设您要将old-fix
合并到feature
,而在feature
中,文件已重命名为FA
。合并意识到它需要从分支old-fix
获取文件(在其旧名称下),并从FA
获取feature
,并合并它们。但是存在合并冲突,您的版本系统会停止并需要您完成合并的帮助。
现在假设您要查看FA
中old-fix
的版本,并将其与FA
中的feature
进行比较。如果您真的检查分支old-fix
,则没有名为FA
的文件!但是git将它存储在索引中,以便您可以看到它,而不必知道旧名称是什么,因为索引正在构建 next 提交(保留新的FA
名称)。
您还可以查看feature
版本,但当然这更容易,因为您知道它的名称为FA
。但它在索引中存在。此外,公共(基础)版本(也与old-fix
中的旧名称相同)位于索引中,如gitrevisions中所述:
A colon, optionally followed by a stage number (0 to 3) and a colon, followed by a path, names a blob object in the index at the given path. A missing stage number (and the colon that follows it) names a stage 0 entry. During a merge, stage 1 is the common ancestor, stage 2 is the target branch's version (typically the current branch), and stage 3 is the version from the branch which is being merged.
也就是说,:1:FA
是文件FA
的共同祖先,:2:FA
是feature
的版本,:3:FA
是old-fix
的版本。
所有这些精细控制都会给初学者(有时甚至是专家)带来一些错误,因此Mercurial的无索引版本可能更适合您的工作。但是,使用git commit -a
,您获得与Mercurial基本相同的行为,因此您可以经常忽略它直到您需要它。