为什么有两种方法来卸载git中的文件?
有时候,gitbuild议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 -ma [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 reset <filePath>
将取消给定文件的任何阶段性变化。
也就是说,如果你在一个新的文件上使用了git rm --cached
,它基本上看起来就像你刚才没有执行过的那样,因为它从来没有被提交过。
git rm --cached
用于从索引中删除文件。 在这个文件已经在repo中的情况下, git rm --cached
将会把这个文件从索引中删除,留在工作目录中,一个提交现在也将它从repo中删除。 基本上,在提交之后,您将会unversioned该文件并保留本地副本。
git reset HEAD file
(默认情况下使用--mixed
标志)与文件已经在repo中的情况不同,它将文件的索引版本replace为来自repo(HEAD)的文件取消对其的修改 。
在未版本化的文件的情况下,由于文件不在HEAD中,因此将整个文件取消。 在这个方面, git reset HEAD file
和git 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 rm --cached <file>
使git完全停止跟踪文件 (把它留在文件系统中,而不像普通的git rm
*) -
git reset HEAD <file>
取消自上次提交以来对git reset HEAD <file>
所做的任何修改 (但不会在文件系统中恢复它们,与命令名称可能会提示**相反)。 该文件保持在修订控制下。
如果这个文件之前没有在版本控制之中(也就是说,你正在初始化一个你刚刚git add
了git add
的文件),那么这两个命令的效果是一样的,因此这两个方法的出现是“做某事“。
*请记住@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 rm --cached to-be-added rm 'to-be-added' # ok me$ git reset -q HEAD to-be-modified # ok me$ git reset -q HEAD to-be-removed # 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 stash git stash pop
这将执行重置为HEAD并重新应用您的更改,允许您重新提交单个文件进行提交。 如果忘记为pull请求创build一个function分支( git stash ; git checkout -b <feature> ; git stash pop
),这也是有帮助的。
这两个命令有几个细微的差别,如果有问题的文件已经在回购和版本控制(以前提交等):
-
git reset HEAD <file>
取消当前提交中的文件。 -
git rm --cached <file>
将会使文件在未来的提交中被取消。 直到它被添加到git add <file>
。
还有一个更重要的区别:
- 运行
git rm --cached <file>
并将你的分支推送到远程,任何从远端拉你的分支的人都会从文件夹中把ACTUALLY文件从文件夹中删除,即使在你的本地工作集中,文件只是不被跟踪从文件夹中物理删除)。
这个最后的区别对于那些包含一个configuration文件的项目很重要,在这个configuration文件中,团队中的每个开发人员都有不同的configuration(即不同的基本URL,ip或者端口设置),所以如果你使用git rm --cached <file>
您的分支将不得不手动重新创buildconfiguration,或者您可以将它们发送给您,并且可以将其重新编辑回它们的ip设置(等等),因为删除只会影响从远程拖动分支的人员。
假设你通过git add <folder>
来完成一个完整的目录,但是你希望从staged列表(即运行git status
时生成的列表)中排除一个文件,并在排除的文件中保留这些修改(你正在做一些事情而且还没有准备好提交,但是你不想失去你的工作…)。 你可以简单地使用:
git reset <file>
当你运行git status
,你会看到你reset
任何文件都是不unstaged
的,而你added
的其他文件仍然在staged
unstaged
列表中。
没有人提到git reflog( http://git-scm.com/docs/git-reflog ):
# git reflog <find the place before your staged anything> # git reset HEAD@{1}
reflog是一个git历史logging,不仅跟踪repo的更改,而且还跟踪用户的操作(例如,pull,checkout到不同的分支等),并允许撤销这些操作。 因此,不要取消上传错误的文件,在这里可以恢复到没有执行文件的地步。
这与git reset HEAD <file>
类似,但在某些情况下可能会更细化。
对不起 – 没有真正回答你的问题,而只是指向另一种方式来取消我经常使用的文件(我喜欢Ryan Stewart的回答,也非常喜欢Waldyrious);)我希望它有帮助。
在我看来, git rm --cached <file>
会从索引中删除文件,而不会将其从一个普通的git rm <file>
可以同时执行的目录中移除,就像OS rm <file>
将删除文件一样从目录中删除其版本。
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 -ma [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 …”来取消)
- 你现在在你的代码中做了一个提交
- 现在你可以重置你的指针,提交' 恢复到上次保存 '
为了解开整个目录,recursion地使用rm(-r)
git rm -r --cached folderpath