2011-04-27 153 views
106

GitRef.org - Basic“git rm --cached x”vs“git reset head -x”?

git rm将会移除 临时区域条目。这是从git reset HEAD有点不同 哪些“unstages” 文件。通过“unstage”,我的意思是在我们开始修改事物之前,它将暂存区域恢复为 。 git rm另一方面只踢 该文件完全退出舞台,所以 它没有包含在下一个 提交快照,从而有效地 删除它。

默认情况下,git rm file将完全从临时区域中删除文件,也会从您的磁盘>(工作目录)中删除该文件。要将文件保留在工作目录中,可以使用git rm --cached

但是究竟是git rm --cached asdgit reset head -- asd之间的区别是什么?

回答

159

有三个地方,一个文件可以是 - 树,索引和工作副本。当你只是添加一个文件到一个文件夹,你将它添加到工作副本。

当您执行类似git add file的操作时,将其添加到索引中。当你提交它时,你也将它添加到树中。

它可能会帮助你了解在git的复位三个比较常见的标志:

git的复位[ - <mode>] [<commit>]

这种形式重置当前分支头<commit>和可能的 更新索引(将其重置为<commit>的树)和 工作树取决于<mode>,它必须是 其中之一翼:
--soft

不触及索引文件,也没有在所有的工作树(但重置 头部<commit>,就像所有的模式做)。这会让您的所有 更改文件“更改为提交”,因为git状态会将其置入。

--mixed

重置索引而不是工作树(即更改的文件 被保留,但不标记为提交)和报告一直没有什么 更新。这是默认操作。

--hard

重置索引和工作树。丢弃对 工作树中自<commit>以来跟踪文件的任何更改。

现在,当你做这样的事情git reset HEAD - 什么你实际上做的是git reset HEAD --mixed,它会“重置”索引你开始之前添加的文件/添加修改,该指数是状态(通过git add在这种情况下,工作副本和索引(或分段)是同步的,但是您在重置后使HEAD和索引同步。

git rm另一方面从工作目录和索引中删除一个文件,当您提交时,文件也从树中删除。然而,git rm --cached仅从索引中删除文件并将其保留在工作副本中。这与git add file完全相反在这种情况下,您使索引与HEAD和工作不同,其中HEAD具有之前承诺的文件版本,工作副本具有las修改,如果有任何或内容来自文件的HEAD,并从索引中删除了该文件。现在提交会同步索引和树,文件将被删除。

+0

我注意到'git rm --cached'后'git diff'命令不显示任何diff,但'git diff --cached'显示diff,就好像它仍然被缓存。然而'git status'显示文件是'Untracked'。似乎有点不一致。 – haridsv 2011-11-06 19:15:01

+4

没关系......我应该使用'git reset --mixed'。我对'git rm --cached'与'git add''相反的说法有点困惑。从字面上看,这是不正确的,可能会造成损害。在我的例子中,我使用'git add'向暂存区添加了一个修改过的文件,并希望“添加”的反义词不是该文件的初始添加。 + Greg Hewgill的回答帮助我获得了更清晰的画面。 – haridsv 2011-11-06 19:19:56

+6

我发现使用工作副本,树和工作树有点混乱。工作树是工作副本还是树? – Nealv 2013-09-23 09:00:15

22

git rm --cached file删除从舞台上的文件。也就是说,当你提交文件时将被删除。 git reset HEAD -- file将简单地将暂存区域中的文件重置为其在HEAD提交上的状态,即将撤消自上次提交以来对其执行的任何更改。如果该更改恰好是新添加文件,那么它们将是等效的。

+6

结合这个概念(正如其他答案中提到的那样)'git rm --cached file'与'git add'相反,这个答案对我来说很有意义,而且非常简洁。几乎与此评论一样短;) – rbatt 2015-12-05 01:37:46

57

也许一个例子有助于:

git rm --cached asd 
git commit -m "the file asd is gone from the repository" 

git reset HEAD -- asd 
git commit -m "the file asd remains in the repository" 

需要注意的是,如果你没有改变任何东西其他,第二承诺实际上不会做任何事情。

+1

你能告诉我什么是双连字符 - HEAD实际上意味着什么? – yuva 2014-11-06 09:22:53

+12

@yuva:'--'用于将命令选项从文件名中分离出来。如果有一个*分支*和一个*文件*命名为'asd',那么'git reset HEAD asd'会不明确。 '--'表示“以下所有内容都是文件名”。 – 2014-11-06 15:55:49

+0

'git reset HEAD '与'git rm --cached '完全一样,然后'git add --intent-to-add '? – 2017-07-28 23:29:43