爲何有兩種方法能夠在Git中取消暫存文件?

有時git建議使用git rm --cached來取消git reset HEAD file文件,有時git reset HEAD file 。 我何時應該使用哪一個? git

編輯: 緩存

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
#

#1樓

這個線程有點舊,但我仍然想添加一些演示,由於它仍然不是一個直觀的問題: spa

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也可用於取消暫存,但會從工做空間中徹底刪除更改 版本控制


#2樓

在我看來, git rm --cached <file>從索引中刪除文件而不將其從普通git rm <file>同時執行這二者的目錄中刪除,就像OS rm <file>將刪除文件同樣從目錄中刪除其版本控制。 code


#3樓

若是有問題的文件已經在repo中且受版本控制(以前已提交等),則這兩個命令有幾個細微差異: 索引

  • git reset HEAD <file>取消暫存當前提交中的文件。
  • git rm --cached <file>也將取消git rm --cached <file>該文件以供未來提交。 它是未分階段的,直到它再次使用git add <file>

還有一個更重要的區別: ip

  • 運行git rm --cached <file>並將分支推送到遠程git rm --cached <file>後,任何從遠程控制器中拉出分支的人都將從其文件夾中刪除文件,即便在本地工做集中文件剛剛未被跟蹤(即不是從文件夾中物理刪除)。

最後一個區別對於包含配置文件的項目很重要,其中團隊中的每一個開發人員都有不一樣的配置(即不一樣的基本URL,ip或端口設置),因此若是你使用git rm --cached <file>任何人拉您的分支必須手動從新建立配置,或者您能夠將它們發送給您的,而且能夠將其從新編輯回其IP設置(等),由於刪除只會影響人們從遠程啓動分支。 開發


#4樓

很簡單: rem

  • git rm --cached <file> 使git徹底中止跟蹤文件 (將其留在文件系統中,與普通的git rm *不一樣)
  • git reset HEAD <file> 取消自上次提交以來對 git reset HEAD <file> 所作的任何修改 (但不會在文件系統中恢復它們,這與命令名稱可能建議的相反**)。 該文件仍在版本控制之下。

若是文件以前沒有處於版本控制之下(即你第一次取消了你剛剛git addgit add的文件),那麼這兩個命令具備相同的效果,所以它們的外觀是「兩種方式作某事「。

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

**因爲它的名字,我懼怕長時間使用git reset命令 - 並且今天我仍然經常查找語法,以確保我不會搞砸。 更新 :我終於花時間在tldr頁面中總結git reset的用法 ,因此如今我有一個更好的心理模型,它是如何工做的,以及當我忘記一些細節時的快速參考。)


#5樓

我很驚訝沒有人提到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的更改,還跟蹤用戶操做(例如,pull,checkout到不一樣的分支等)並容許撤消這些操做。 所以,不是取消暫停錯誤播放的文件,而是能夠恢復到不放置文件的位置。

這與git reset HEAD <file>相似,但在某些狀況下可能更精細。

對不起 - 沒有真正回答你的問題,但只是指出另外一種方式來取消我常用的文件(我很是喜歡Ryan Stewart和waldyrious的回答。);)我但願它有所幫助。

相關文章
相關標籤/搜索