2011-04-27 155 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