git reset vs git reset HEAD

时间:2015-11-21 23:09:21

标签: git git-reset unstage

每次播放文件时,Git都会在您需要取消暂存文件时提供有用的说明:

(use "git reset HEAD <file>..." to unstage)

然而,体面的Git Tutorials by Atlassian只是说:

git reset <file>

这似乎更直接,为什么差异呢?

3 个答案:

答案 0 :(得分:17)

在默认参数方面没有区别(来自git reset man page):

  

所有表格中的<tree-ish>/<commit>默认为HEAD

该消息最初包含HEAD:commit 3c1eb9c, Jan. 2007, git 1.5.0-rc1,但由于默认情况下总是已知,所以帮助消息清楚地说明了哪个提交你应该重置。

HEAD出现在commit 367c988, Nov. 2007, Git 1.5.4

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)

torek指出实际差异in the comments

  

通过指定HEAD,您可以保证HEAD之后的第一个单词被视为路径名。
  例如,假设您运行git reset zorgzorg是树名,例如标记名称,还是路径名./zorg
  Git的答案是:如果git rev-parse可以将其转换为树ID,那么它就是树状结构,否则它就是一条路径。
  您可以写git reset -- zorggit reset HEAD zorg以确保git将其视为路径。

详情请参阅“Deleting a badly named git branch”中的双连字符语法(--)。

OP skube添加in the comments

  

另外,他们确实建议放弃工作目录的变更   (即git checkout -- <file>)   它似乎与git reset HEAD <file>不一致。

虽然git reset man page清楚地表明git reset <tree-ish> -- <paths>中缺少树形,但这意味着HEAD,git checkout <tree-ish> -- <paths>并非如此。

git checkout <tree-ish> -- <pathspec>
  

<paths>被给出时,git checkout不会切换分支   它从索引文件或命名的<tree-ish>(通常是提交)更新工作树中的命名路径。

这意味着git checkout -- path将使用已经暂存的内容覆盖工作树(git add'ed。) 虽然git reset -- PATH(作为git重置的混合形式)将使用HEAD包含的内容重置索引(有效地取消暂存所添加的内容)

git resetgit checkout不使用相同的默认值,并且:

  • 您可以代表git reset <tree-ish> <file>的默认树:HEAD 因此git reset HEAD <file>;
  • 但是当您没有为git checkout提供树时,您无法表示默认参数:它是索引。
    因此git checkout -- file

--必须使用git checkout,因为只有一个参数,需要明确参数代表文件

请注意,git checkout HEAD files不同:torek提及in the comments

  

git checkout HEAD pathHEAD提交(tree-ish)复制到索引,然后再转到工作目录。

答案 1 :(得分:2)

默认情况下,git reset相当于git reset HEAD

引用手册页(我的重点):

  

git-reset - 将当前HEAD重置为指定状态。

git reset [-q] [<tree-ish>] [--] <paths>…
git reset (--patch | -p) [<tree-ish>] [--] [<paths>…​]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
     

在第一种和第二种形式中,复制来自&lt; tree-ish&gt;的条目。到索引。在第三种形式中,可选地将当前分支头(HEAD)设置为&lt; commit&gt;   修改索引和工作树以匹配。 &lt; tree-ish&gt; /&lt; commit&gt;   默认为所有表格中的HEAD。

     

[...]

git reset [-q] [<tree-ish>] [--] <paths>…​
     

此表单重置所有&lt;路径&gt;的索引条目。到他们在&lt; tree-ish&gt;的状态。 (它不会影响工作树或当前的工作   分支。)

     

这意味着git reset <paths>git add <paths>相反。

从中可以看出行为没有实际差异。

  

这似乎更直接,为什么差异呢?

既然它们都是一样的,你也可以使用两者中最短的版本。

答案 2 :(得分:1)

第一次,在任何提交之前HEAD不存在,那么我们得到:

$git reset HEAD stagedFile
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree