簡體   English   中英

為什么有兩種方法可以在 Git 中取消暫存文件?

[英]Why are there two ways to unstage a file in Git?

有時 git 建議git rm --cached取消暫存文件,有時git reset HEAD file 我什么時候應該使用哪個?

編輯:

D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

D:\code\gt2>touch b

D:\code\gt2>git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add b

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

git rm --cached <filePath>不會取消git rm --cached <filePath>文件,它實際上會git rm --cached <filePath>從存儲庫中刪除文件(假設它之前已經提交)但將文件留在您的工作樹中(讓您留下未跟蹤的文件)文件)。

git reset -- <filePath>取消暫存給定文件的任何暫存更改。

也就是說,如果您在git rm --cached的新文件上使用git rm --cached ,它基本上看起來就像您剛剛取消暫存,因為它以前從未被提交過。

更新 git 2.24
在這個較新版本的 git 中,您可以使用git restore --staged而不是git reset 請參閱git 文檔

git rm --cached用於從索引中刪除文件。 如果文件已經在 repo 中, git rm --cached將從索引中刪除該文件,將其保留在工作目錄中,現在提交也會將其從 repo 中刪除。 基本上,在提交之后,您將取消版本化文件並保留本地副本。

git reset HEAD file (默認情況下使用--mixed標志)的不同之處在於,在文件已經在 repo 中的情況下,它將文件的索引版本替換為來自 repo (HEAD) 的索引版本,有效地取消對它的修改

在未版本化文件的情況下,它將取消整個文件的暫存,因為該文件不在 HEAD 中。 在這方面git reset HEAD filegit rm --cached是相同的,但它們不一樣(如已在 repo 中的文件的解釋)

關於Why are there 2 ways to unstage a file in git?取消Why are there 2 ways to unstage a file in git? - 在 git 中做任何事情的方法從來都不是只有一種。 這就是它的美妙之處:)

很簡單:

  • git rm --cached <file>使 git 完全停止跟蹤文件(將其留在文件系統中,與普通的git rm * 不同)
  • git reset HEAD <file>取消自上次提交以來對git reset HEAD <file>所做的任何修改(但不會在文件系統中恢復它們,這與命令名稱可能暗示的相反**)。 該文件仍處於修訂控制之下。

如果該文件之前不在修訂控制中(即您正在取消git add您剛剛git add ed 的第一次文件),那么這兩個命令具有相同的效果,因此它們的外觀是“兩種方式做某事”。

* 請記住@DrewT 在他的回答中提到的警告,關於之前提交到存儲庫的文件的git rm --cached 在這個問題的上下文中,對於剛剛添加但尚未提交的文件,沒有什么可擔心的。

** 由於它的名字,我很長時間都害怕使用 git reset 命令——直到今天我仍然經常查看語法以確保我沒有搞砸。 更新:我終於花時間在 tldr 頁面中總結了git reset的用法,所以現在我對它的工作方式有了一個更好的心理模型,以及當我忘記一些細節時的快速參考。)

這個線程有點老了,但我還是想補充一點演示,因為它仍然不是一個直觀的問題:

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD (不帶-q )給出關於修改文件的警告,其退出代碼為 1,這將被視為腳本中的錯誤。

編輯: git checkout HEAD to-be-modified to-be-removed也適用於取消暫存,但從工作區中完全刪除更改

更新 git 2.23.0:命令會不時更改。 現在, git status說:

  (use "git restore --staged <file>..." to unstage)

... 適用於所有三種類型的變化

如果您不小心暫存了您不想提交的文件,並希望確保保留更改,您還可以使用:

git stash
git stash pop

這會重置 HEAD 並重新應用您的更改,從而允許您重新暫存單個文件以進行提交。 如果您忘記為拉取請求創建功能分支( git stash ; git checkout -b <feature> ; git stash pop ),這也很有幫助。

如果有問題的文件已經在 repo 中並且在版本控制之下(以前提交等),這 2 個命令有幾個細微的區別:

  • git reset HEAD <file>在當前提交中取消暫存文件。
  • git rm --cached <file>也將取消git rm --cached <file>文件以備將來提交。 在使用git add <file>再次git add <file>它是未git add <file>

還有一個更重要的區別:

  • 運行后git rm --cached <file> ,並把你的分支到遠程,任何人從遠程拉你的分公司將充分利用自己的文件夾中實際刪除文件,即使在您的本地工作僅有變成未被跟蹤的文件(即不從文件夾中物理刪除)。

最后一個區別對於包含配置文件的項目很重要,其中團隊中的每個開發人員都有不同的配置(即不同的基本 url、ip 或端口設置),因此如果您使用git rm --cached <file>任何人您的分支必須手動重新創建配置,或者您可以將您的配置發送給他們,他們可以將其重新編輯回他們的 ip 設置(等),因為刪除只會影響人們從遠程拉出您的分支。

比方說,你stage通過整個目錄git add <folder> ,但要排除一個文件從分級列表(即運行時產生的列表git status ),並保持已排除的文件中修改(您正在使用的東西它尚未准備好提交,但您不想丟失您的工作......)。 你可以簡單地使用:

git reset <file>

當您運行git status ,您將看到您reset任何文件unstaged ,而您added的其余文件仍在staged列表中。

1.

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

(使用“git rm --cached ...”取消暫存)

  • git 是一個指針系統

  • 您還沒有提交將指針更改為

  • “從指向的存儲桶中取出文件”的唯一方法是刪除您告訴 git 監視更改的文件

2.

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

git commit -ma

  • 你承諾,“保存

3.

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

(使用“git reset HEAD ...”取消暫存)

  • 您此時在代碼中進行了提交
  • 現在您可以將指針重置為您的提交“恢復到上次保存

只需使用:

git reset HEAD <filename>

這會取消暫存文件並保留您對它所做的更改,因此您可以反過來,如果需要,更改分支,然后git add這些文件git add到另一個分支。 保留所有更改。

我很驚訝沒有人提到 git reflog ( http://git-scm.com/docs/git-reflog ):

# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

reflog 是一個 git 歷史記錄,它不僅可以跟蹤對 repo 的更改,還可以跟蹤用戶操作(例如拉取、結帳到不同分支等)並允許撤消這些操作。 因此,您無需取消暫存錯誤暫存的文件,而是可以恢復到未暫存文件的位置。

這類似於git reset HEAD <file>但在某些情況下可能更精細。

抱歉 - 沒有真正回答你的問題,只是指出了另一種我經常使用的取消暫存文件的方法(我非常喜歡 Ryan Stewart 和 waldyrious 的答案。);)我希望它有所幫助。

僅適用於 2.23 及以上版本,

代替這些建議,您可以使用git restore --staged <file> ,以unstage文件(縣)。

在我看來, git rm --cached <file>會從索引中刪除文件,而不會將其從普通git rm <file>將同時執行這兩項操作的目錄中刪除,就像操作系統rm <file>會刪除文件一樣從目錄中刪除其版本控制。

在 > 2.2 的較新版本中,您可以使用git restore --staged <file_name> 請注意這里如果您想一次取消暫存(移動到更改)您的文件,請使用上述命令和您的文件名。 例如

git restore --staged abc.html

現在,如果您想一次取消所有文件的暫存,您可以執行以下操作

git restore --staged .

請注意空格和點(.),這意味着考慮暫存所有文件。

取消暫存文件(撤消 git add)

git restore --staged file.js # 將最新版本的 file.js 從 repo 復制到 index

丟棄本地更改

git restore file.js # 將 file.js 從索引復制到工作目錄

git restore file1.js file2.js # 恢復工作目錄下的多個文件

混帳恢復。 # 丟棄所有本地更改(未跟蹤的文件除外)

git clean -fd # 刪除所有未跟蹤的文件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM