我在> 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_branch
。
feature
说(我把文件名放在引号中以使其显而易见):
git status --short
.gitignore是空的。
D "D1"
D "D2"
M "M"
说:
git diff --name-status feature develop
M "D1"
命令仅产生提交ID。
答案 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
是否包含文件D
和D2
。 (通常最好显示每个命令的确切输出,以防这里出现一些微妙的内容。)但是,运行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
前面的前导空格。 那意味着文件D
和D1
已被明确删除,但不是D2
- ed。
(也许实际的输出是:
git rm
请注意每个字母代码和文件名之间的两个空格。在这种情况下,两个D D1
D D2
M M
文件已 D
- ed,文件git rm
为M
- ed。但你说&#34;什么都没有上演&#34;所以我假设一个空格,然后是字母代码,然后是一个空格,然后是文件名。)
如果没有暂存,则索引(或暂存区域)必须与当前提交匹配(记住,git add
:F
指向分支名称HEAD
和分支-name feature
指向提交feature
)。由于F
在每个字母代码之前都有空格,这也告诉我们索引与git status --short
提交具有相同的条目,即没有为新提交暂存。
但我们确实看到了两个HEAD
(已删除)文件:D
和D1
都显示为已从工作树中删除。要从工作树中删除,它们必须位于索引中。这意味着现在索引中的文件D2
和D1
都是 - 正如我们刚才所说,索引与D2
提交匹配。同样,我们看到了一个HEAD
文件。要进行修改,文件M
必须在索引中,因此在提交M
中。这告诉我们有关当前F
提交HEAD
的更多信息。让我们写下来。
我们现在确定文件F
,D1
和D2
在提交M
中都是三个。 和,我们跑了:
F
这告诉我们提交$ git diff --name-status feature develop
M "D1"
中的文件D1
,D2
和M
!
显然,D
上的D1
提交D
和develop
上的提交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 develop
,D
和D1
。我们还知道索引中的D2
版本与提交M
的版本匹配,因此与提交D1
中F
的版本不同
这意味着要使D1
成功,它必须将文件D
的版本从提交git checkout develop
提取到索引,从而提取到工作树。这不会破坏任何现有文件,因为D1
的工作树版本已经消失。 Git把这个操作放在&#34;工作的队列中。在实际执行之前,然后继续寻找更多工作,因为它需要确保整个结账都没问题,然后一次性完成所有工作,否则停止并且什么都不做。
Git需要在索引中更改哪些 else ?好吧,它会查看文件D
的索引内容,但是D1
和D2
中的相同,所以要从{{切换1}}到F
,没有任何关系。它还会查看文件D
的索引内容,但同样,F
和D
中的相同:&#39;什么都不做。
(它还必须比较提交M
和/或当前索引中的任何和所有其他文件,但这些文件也匹配。)
所以,现在确定没有任何文件会被破坏,Git会回到工作队列,它会将#{1}提取文件从F
提取到索引和工作中-tree&#34 ;.它会这样做,然后更新D
以引用D
(然后指向提交D1
),结帐完成。
为什么它没有抱怨&#34; M&#34;被修改 - 即使它尚未提交?
在某些理论意义上,它可能应该至少在某些情况下,某些版本的Git似乎应该这样做。但是,正如我们所看到的,D
的索引版本在.git/HEAD
和develop
都匹配,因此D
根本不需要更改M
。您的特定版本的Git不仅不会更改F
,它甚至不会费心去查看D
被修改。所以它不会打印git checkout
。
无论如何,这就是答案:M
找到可以做的最少工作量。由于提交M
和M
仅在文件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可以自由地破坏它!)