关于git reset:为什么在git中有两种方法可以解除文件的存储?

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

有时git建议git rm --cached取消文件的存储,有时git reset HEAD file。我什么时候应该用哪个?

编辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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 不会解除文件的固定,它实际上会将文件从repo中删除(假设以前已经提交过),但会将文件保留在工作树中(留下未跟踪的文件)。

git reset -- 将取消对给定文件的任何阶段性更改。

也就是说,如果你在一个新的文件上使用git rm --cached,它基本上看起来像是你刚刚取消了它,因为它以前从未被提交过。


git rm --cached用于从索引中删除文件。如果文件已经在repo中,git rm --cached将从索引中删除该文件,并将其保留在工作目录中,而commit现在也将从repo中删除该文件。基本上,在提交之后,您将取消文件的版本控制并保留一个本地副本。

git reset HEAD file(默认使用--mixed标志)与repo(head)中的索引版本不同,它将文件的索引版本替换为repo(head)中的索引版本,有效地解除了对该文件的修改。

在未版本化的文件中,由于文件不在头中,所以它将取消整个文件的版本化。在这方面,git reset HEAD filegit rm --cached是相同的,但它们是不同的(正如在repo中已经存在的文件中所解释的那样)。

关于Why are there 2 ways to unstage a file in git?的问题,在git中从来没有一种真正的方法可以做任何事情。这就是它的美:)


很简单:

  • git rm --cached 让Git跟踪文件(我完全停止在它的文件,不同的平git rm*)
  • git reset HEAD unstages任何修改文件从制造到最后的承诺(但不是在文件系统恢复他们的命令名称,相反有可能suggest **)。该文件是根据修正的控制。

如果文件是不是在以前的版本控制(即你的文件,你就有unstaging git added是第一时间),然后在这两个命令有相同的效果,因此在这两方面表现为:做什么。"

组分保持心灵的"*"drewt mentions在他的答案,对于git rm --cached)这是以前的文件提交到数据库。在当前这一问题的文件,只是由美国并没有承诺,没有什么可担心的。> < /次

<一> *分为一embarrassingly害怕的是长时间使用的Git命令的名称,因为它的复位和今天的我仍然经常查找的语法来确保I Don’t螺钉上。更新:我终于把《Time to the usage of git resetsummarize源页面中,所以现在我有一个更好的心理模型和它是如何工作的,当我快忘了一些细节的参考。)></分


这个线程有点旧,但我还是想添加一些演示,因为它仍然不是一个直观的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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也适用于取消老化,但将更改完全从工作区中删除。


"如果你accidentally阶段文件,你将不喜欢承诺,和你保持一定要被改变,你也可以使用:

1
2
git stash
git stash pop

这头和执行复位(重新适用你的改变,让你重新提交的文件是个人的阶段。这是一helpful也."如果你是拉到创建特征分公司(git stash ; git checkout -b ; git stash pop)的要求。


如果所讨论的文件已经在repo中并且在版本控制下(以前提交的等),这两个命令有几个细微的区别:

  • git reset HEAD 取消当前提交中的文件。
  • git rm --cached 也将取消文件的保存,以备将来提交。它是不稳定的,直到它与git add 再次添加。

还有一个更重要的区别:

  • 在运行git rm --cached 并将您的分支推到远程之后,从远程拉您的分支的任何人都将从其文件夹中实际删除该文件,即使在本地工作集中,该文件只是未被跟踪(即,未从文件夹中物理删除)。

最后一个区别对于包含配置文件的项目很重要,其中团队中的每个开发人员都有不同的配置(即不同的基本URL、IP或端口设置),因此,如果使用git rm --cached ,则任何拉过分支的人都必须手动重新创建配置,或者您可以将其发送给他们,然后他们可以将其重新编辑回自己的配置文件。IP设置(等),因为删除只影响从远程拉分支的人。


1。

1
2
3
4
5
6
7
8
9
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 -中……"unstage)

  • Git是一个系统的分

  • 你还没有提交你的指针的变化。

  • 唯一的办法以斗尖出的文件被删除的文件,你是来告诉Git到监视的变化

2。

1
2
3
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 - M的

  • 允许你保存","

3。

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

(使用`git reset头……"unstage)

  • 你将在你的代码在制造时。
  • 现在你可以重置你的指针到您的提交恢复回到最后的拯救"


让我们说你是全git add stage目录路径,但你想从列表中排除的文件阶段(即运行时生成的列表,git status)和保持在排除文件(修改的东西和你的工作不是做准备,但你不想失去你的工作……)。你可以简单的使用:

git reset

当你运行,你会看到这git status,无论你reset文件(s)是unstaged和休息你的文件stagedadded仍然在名单上。


没人提到我的surprised Git reflog(http://git-scm.com /文档/把reflog):

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

这是一reflog git的历史轨迹的变化不仅对回购行为的用户,但也有轨道(如检测到的不同分。拉,等),和让那些对世界的影响。而在操作系统级的文件这是mistakingly unstaging,你可以恢复到该点的地方在这里你didn’t级的文件。

这是类似于在某些情况下可能是git reset HEAD 但更多的颗粒。

对不起,你的问题不是真的自愿,但只是到了另一种方式来指责我unstage文件更经常使用(一)一样的答案非常感谢斯图尔特和waldyrious)。);我希望它帮助。


在我看来,git rm --cached 从索引中删除文件,而不从普通git rm 可以同时执行这两种操作的目录中删除文件,就像OS rm 在不删除其版本的情况下从目录中删除文件一样。