哪些文件" git checkout"修改?

时间:2016-10-03 01:57:09

标签: git

我在> let x = mkFieldElem 6 :: FieldElem 11 Error: No instance for (Prime 11) > case witPrime (Proxy :: Proxy 11) of Just Dict -> let x = mkFieldElem 6 :: FieldElem 11 -- okay, because of Dict constructor match in print x FieldElem 6 -- :: FieldElem 11 分行,想要结帐到feature

相对于develop分支,在我的develop分支文件" D1"被修改了。

相对于feature分支,在我的工作树文件中" M"被修改了," D1"和" D2"被删除了。

相对于develop分支,我的工作树当然有文件" D1"和" D2"删除," M"改性。什么都没有上演。

当我运行feature时,git添加了文件" D1"到工作树,但没有做任何关于" D2"和" M"。为什么git会对待" D1"和" D2"不同?为什么它没有抱怨" M"被修改 - 即使它尚未提交?

我尝试按照this SO answer中有关哪些文件git checkout develop可以安全修改的说明进行操作。但要理解这一结果还不够。

编辑(回答@torek评论):

最初,我在git checkout new_branchfeature说(我把文件名放在引号中以使其显而易见):

git status --short

.gitignore是空的。

D "D1" D "D2" M "M" 说:

git diff --name-status feature develop

M "D1" 命令仅产生提交ID。

1 个答案:

答案 0 :(得分:1)

设置

我们这里没有原始提交ID,但我们并不需要它们。我们也无法绘制大部分提交图,但我们也不需要它。但是,仅仅为了具体而言,我会画一些假装的,只是为了有东西可以参考,我们不必写出名字feature和{{ 1}}。

我们所拥有的是两个不同的提交(它们是提交图的一部分),索引和工作树。我们最初也在分支develop上。

关于两次提交的一些明确的事情

让我们先提交提交:

feature

提交...--A--B--...--D <-- develop \ C--...--F <-- HEAD -> feature 是分支D的提示,提交develop是分支功能的提示。由于我们位于分支F上,因此文件feature包含名称.git/HEAD,这就是Git知道如何使用/在分支feature上工作。

提交feature包含一堆文件,至少包括文件D。从上述所有输出中可以看出,提交D1是否包含文件DD2。 (通常最好显示每个命令的确切输出,以防这里出现一些微妙的内容。)但是,运行M应该打印出来:

git status --short

这不是很正确。 (这里是来自不同D "D1" D "D2" M "M" 的实际输出:

git status --short

请注意$ git status --short M pytest/p9conn.py ?? backend/backend.h+ 前面的前导空格,位于下一行的第一个pytest/p9conn.py之上:这表示输出中的?告诉我们修改位于索引和工作树,而不是当前的提交和索引。)我打算假设它打印出来:

M

包括每个 D D1 D D2 M M 前面的前导空格。 意味着文件DD1已被明确删除,但不是D2 - ed。

(也许实际的输出是:

git rm

请注意每个字母代码和文件名之间的两个空格。在这种情况下,两个D D1 D D2 M M 文件 D - ed,文件git rmM - ed。但你说&#34;什么都没有上演&#34;所以我假设一个空格,然后是字母代码,然后是一个空格,然后是文件名。)

索引/登台区域和工作树

如果没有暂存,则索引(或暂存区域)必须与当前提交匹配(记住,git addF指向分支名称HEAD和分支-name feature指向提交feature)。由于F在每个字母代码之前都有空格,这也告诉我们索引与git status --short提交具有相同的条目,即没有为新提交暂存。

但我们确实看到了两个HEAD(已删除)文件:DD1都显示为已从工作树中删除。要从工作树中删除,它们必须位于索引中。这意味着现在索引中的文件D2D1都是 - 正如我们刚才所说,索引与D2提交匹配。同样,我们看到了一个HEAD文件。要进行修改,文件M 必须在索引中,因此在提交M中。这告诉我们有关当前F提交HEAD的更多信息。让我们写下来。

关于两次提交的更明确的事情

我们现在确定文件FD1D2在提交M中都是三个。 ,我们跑了:

F

这告诉我们提交$ git diff --name-status feature develop M "D1" 中的文件D1D2M

显然,D上的D1提交Ddevelop上的提交F,因为 < / em>两个分支之间。

但是现在我们知道文件feature在两次提交中都提交并且 相同。我们知道这一点,因为我们从D2输出证明了git status在提交D2中。如果F未提交D2,则在查看如何从提交D更改为提交{{1}时,我们会将其视为已删除 }。我们没有看到,所以不能删除它。此外,它们在两次提交中必须相同:如果它们不同,我们会在看到如何从F更改时将其视为已修改D

文件F也是如此。我们在D输出中看不到它,因此它必须存在于M顶端的提交git diff --name-status中,并且它必须与此处的位置相同D

develop

  

当我运行git checkout develop时,git添加了文件&#34; D1&#34;到工作树,但没有做任何关于&#34; D2&#34;和&#34; M&#34;。为什么git会对待&#34; D1&#34;和&#34; D2&#34;不同?

方式feature(需要在某种程度上切换工作树内容,尝试匹配提交git checkout)它的工作从比较当前索引到目标提交。

我们知道当前索引中包含文件git checkout developDD1。我们还知道索引中的D2版本与提交M的版本匹配,因此与提交D1F的版本不同

这意味着要使D1成功,它必须将文件D的版本从提交git checkout develop提取到索引,从而提取到工作树。这不会破坏任何现有文件,因为D1的工作树版本已经消失。 Git把这个​​操作放在&#34;工作的队列中。在实际执行之前,然后继续寻找更多工作,因为它需要确保整个结账都没问题,然后一次性完成所有工作,否则停止并且什么都不做。

Git需要在索引中更改哪些 else ?好吧,它会查看文件D的索引内容,但是D1D2中的相同,所以要从{{切换1}}到F,没有任何关系。它还会查看文件D的索引内容,但同样,FD中的相同:&#39;什么都不做。

(它还必须比较提交M和/或当前索引中的任何和所有其他文件,但这些文件也匹配。)

所以,现在确定没有任何文件会被破坏,Git会回到工作队列,它会将#{1}提取文件从F提取到索引和工作中-tree&#34 ;.它会这样做,然后更新D以引用D(然后指向提交D1),结帐完成。

  

为什么它没有抱怨&#34; M&#34;被修改 - 即使它尚未提交?

在某些理论意义上,它可能应该至少在某些情况下,某些版本的Git似乎应该这样做。但是,正如我们所看到的,D的索引版本在.git/HEADdevelop都匹配,因此D根本不需要更改M。您的特定版本的Git不仅不会更改F,它甚至不会费心去查看D被修改。所以它不会打印git checkout

无论如何,这就是答案:M找到可以做的最少工作量。由于提交MM仅在文件M M的内容上有所不同,这是最低限度的工作:更改存储在索引中的git checkout的内容工作树

有时还有更多的工作:除了更改文件内容外,有时候D必须创建一个文件(来自F差异来自&#34;当前提交&#34;建议结帐&#34;,显示为D1 dded)。有时D1必须删除一个文件(在#34中的差异;当前提交&#34;到&#34;建议结帐&#34;,显示为git checkout eleted)。当然,可能的是,这些文件可能存在于工作树中(无论它们是否在索引中)而不是根本不存在,而这些文件可能存在于 don't匹配一个或两个提交。在这些情况下,Git必须非常小心工作树内容。 (这是--name-status开始重要的时候:如果A中列出了一个文件,Git可以自由地破坏它!)