我在SO上看过following问题,它询问如何跟踪但不能分阶段以及如何取消暂停但不在git中取消攻击文件。作为一个git初学者,我很好奇这两个案例在哪些特定场景中有用?
答案 0 :(得分:0)
从技术上讲,你不能"跟踪而不是阶段"一个文件,也不是某种意义上的#34;没有未跟踪",除了Git和人都使用" unstage"引用别的东西。 (我将描述"非舞台"稍微结束意义。)
跟踪文件""在Git中,如果它有一个Git称之为" index",又名" staging area"的条目。 git add
和git rm
都会在索引中创建或替换一个条目 - git rm
放入一个" whiteout"输入,意思"它刚才在这里,但在我提交后,让它不在这里,以便它不再被跟踪。" (事实上,git add
可以像git rm --cached
那样行事,如果文件在索引中但在工作树中丢失,则会这样做。)
您可以使用git ls-files --stage
查看(大部分)索引中的内容;见下面的例子。最多有四个索引"插槽"每个文件路径名称。其中三个仅在合并期间使用。因此,除了合并之外,索引中的所有内容始终处于"阶段零"。
要暂存文件,我们只需运行git add path
(或git add -- path
,如果路径部分类似于{{{ 1}},虽然您也可以将文件-p
命名为-p
,以防止它看起来像补丁标记)。如果文件已经在索引中,则更新(通过替换现有索引条目)。
To" unstage"一个文件,我们通常运行./-p
(必要时添加git reset path
,如前所述)。但是,除了一个案例,此不会删除路径的索引条目!相反,它重置(因此名称)索引条目以匹配--
提交。完全删除条目的一种情况是HEAD
提交在该路径名下没有文件。
因此," unstaging"一个文件实际上不是 un -stage文件:相反,它重新 - 阶段(或更好,重置)它回到当前(HEAD)提交,但不触及工作树中的副本。但是,每个人都使用" unstage"对于这个动作,所以我们不妨习惯它。 : - )
您与使用HEAD
的谈话相关联的问题。这在Git版本2.5中已经完全被破解了一段时间,并且在Git 2.10.1中仍然部分被破坏了(我只是在我的测试中)。它有效地将占位符放入索引中,以便 跟踪文件(当然,因为它在索引中),但同时在那里没有实际的文件。此索引条目标记为" special",非常类似于whiteout条目。该行为实际上与whiteout条目非常相似 - 即,git add -N
将文件写入结果树 - 除了在提交后保留意图添加特殊条目,而提交后将删除whiteout条目。
至于使用这有什么:在我看来,它没有。 :-)显然,解决错误(2.5以下的Git版本git write-tree
完全失败,2.5到2.10中的小问题)并不是非常重要,因此可能很少有人(如果有的话)实际使用它。
它确实完成的一件事是让-N
将文件视为已跟踪,以便将当前索引与工作树进行比较的git diff
将文件的内容显示为加入:
git diff
(这表示"第三个文件"未跟踪)
$ git status --short
?? thirdfile
(无输出:$ git diff
不查看未跟踪的文件)
git diff
(这表明该文件现在在索引中被跟踪,而不是在$ git add -N thirdfile
$ git status --short
AM thirdfile
提交中,因此状态HEAD
作为第一个字母 - 并且也被修改,因为索引条目是假的但该文件存在真实内容)
A
(这里我们看到真实的内容)。如果我们使用$ git diff
diff --git a/thirdfile b/thirdfile
index e69de29..1ecbedd 100644
--- a/thirdfile
+++ b/thirdfile
@@ -0,0 +1 @@
+data for file 3
来查看索引,我们会看到 1 一个阶段为零的条目 - 一个普通文件 - 其哈希是空文件的哈希:
git ls-index --stage
如果我们清空文件,工作树中的真实文件现在与存储在索引中的哈希相匹配。奇怪的是,虽然$ git ls-files --stage
100644 e5c143f6fec374d115ef674fc036649d78c625d2 0 README
100644 6b8bd59d197cba9032b59ee3aa3f4e71cfbdc2df 0 dummyfile
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 thirdfile
$ git hash-object -t blob --stdin < /dev/null
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
现在没有显示任何内容,git diff
仍然表示文件被修改,与索引版本相比:
git status
(最后一个命令不产生输出)。这是一个文件,其缓存条目被标记为&#34;意图添加&#34;始终被视为&#34;修改&#34;当与工作树相比时,是Git 2.10.1&#34;中部分断开的来源。 case,因为即使新提交的内容与$ : > thirdfile
$ git status --short
AM thirdfile
$ git diff
提交内容相匹配,这也会使git commit
愚弄允许提交。
一旦你HEAD
(没有git add
)文件,假冒&#34;意图在索引中添加&#34; -flagged stage-0条目就成了真实blob的真实条目(即文件),其中实际哈希指向存储库中的真实对象。也就是说,真正的条目会覆盖假的条目。如果您首先从工作树中删除该文件,然后在该路径上运行-N
,Git将完全删除特殊标记的索引条目,就像Git在其上运行git add
一样。这与在真实(非特殊标记)文件上使用git rm --cached
不同,Git在索引中写入了一个white-out条目。 2
1 目前尚不清楚为什么 git rm --cached
会显示这些意图添加标记的条目。相同的命令跳过白名单。
2 我们可以使用git ls-files --staged
查看whiteout条目。我们只需在工作树中创建文件,或使用git status --short
,以便在将white-out条目写入索引时文件保留在工作树中。此时git rm --cached
不显示文件,git ls-files --stage
将文件显示为已删除,git diff
将文件显示为已删除以及未跟踪,git status
为文件生成两个条目:
git status --short
要拥有$ git rm --cached secondfile
$ git status --short
D secondfile
?? secondfile
?? thirdfile
条目,索引中必须包含某些内容;但要获得D
条目,Git必须假装索引中没有任何内容。因此,此处有一个??
的whiteout条目,在索引的某些扫描中可见,但secondfile
没有,这只是我刚才在索引中作为其中一个意图添加虚假条目。