每次暂存文件时,Git 都会在您需要取消暂存文件时提供有用的说明:
(use "git reset HEAD <file>..." to unstage)
然而,Atlassian的不错的Git 教程只是简单地说:
git reset <file>
这似乎更直接,那么为什么有区别呢?
每次暂存文件时,Git 都会在您需要取消暂存文件时提供有用的说明:
(use "git reset HEAD <file>..." to unstage)
然而,Atlassian的不错的Git 教程只是简单地说:
git reset <file>
这似乎更直接,那么为什么有区别呢?
在默认参数方面没有区别(来自git reset
手册页):
<tree-ish>/<commit>
默认为所有HEAD
形式。
该消息最初不包括 HEAD: commit 3c1eb9c, Jan. 2007, git 1.5.0-rc1,但由于默认值并不总是已知的,因此帮助消息清楚地表明您应该重置哪个提交。
HEAD
出现在提交 367c988,2007 年 11 月,Git 1.5.4 中:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
通过指定
HEAD
,您可以保证将后面的第一个单词HEAD
作为路径名。
例如,假设您运行git reset zorg
. 是zorg
树状的,例如标签名称,还是路径名称./zorg
?
Git 的回答是:如果git rev-parse
可以将其转换为树 ID,则它是树状的,否则它是路径。
您可以编写git reset -- zorg
或git reset HEAD zorg
确保 git 将其视为路径。
请参阅“删除名称错误的 git 分支--
”中有关双连字符语法 ( ) 的更多信息。
顺便说一句,他们确实建议使用它来丢弃工作目录
(即git checkout -- <file>
)中的更改。
它似乎与git reset HEAD <file>
.
虽然git reset
手册页清楚地表明在 HEAD 中缺少树状结构git reset <tree-ish> -- <paths>
,但对于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 reset 的混合形式)将使用 HEAD 包含的内容重置索引(有效地取消暂存添加的内容)
git reset
并且git checkout
不要使用相同的默认值,并且:
git reset <tree-ish> <file>
您可以为:表示默认树HEAD
。git reset HEAD <file>
;git checkout
:它是索引。git checkout -- file
。在这种情况下--
必须使用git checkout
,因为只有一个参数,并且需要明确参数代表files。
请注意,这git checkout HEAD files
是不同的:torek在评论中提到
git checkout HEAD path
从HEAD
提交(树状)复制到索引,然后复制到工作目录。
注意:对于 Git 2.23+,2019 年 8 月,您可以git restore
改用
请参阅示例:
恢复索引中的文件以匹配 HEAD 中的版本(这与使用相同
git-reset
)$ git restore --staged hello.c
手册页:
git restore --staged hello.c
不指定源,仅恢复索引 ( --staged
):它使用 HEAD 作为源(默认情况下)这样做。
默认情况下,工作树和索引的恢复源分别是索引和 HEAD。
--source
可用于将提交指定为还原源。
其他示例:
您可以恢复索引和工作树(这与 using 相同
git-checkout
)$ git restore --source=HEAD --staged --worktree hello.c
或者更实用但可读性较差的简短形式:
$ git restore -s@ -SW hello.c
git restore
是一个更自然的命令名称,并且没有歧义。
默认情况下,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>]
在第一种和第二种形式中,将条目从 <tree-ish> 复制到索引。在第三种形式中,将当前分支头 (HEAD) 设置为 <commit>,可选择修改索引和工作树以匹配。<tree-ish>/<commit> 在所有形式中默认为 HEAD。
[...]
git reset [-q] [<tree-ish>] [--] <paths>…
这种形式将所有 <paths> 的索引条目重置为它们在 <tree-ish> 的状态。(它不会影响工作树或当前分支。)
这意味着
git reset <paths>
与 相反git add <paths>
。
从这里您可以看到行为没有实际差异。
这似乎更直接,那么为什么有区别呢?
由于它们都是相同的,因此您不妨使用两者中最短的版本。
第一次,在任何提交之前 HEAD 不存在,然后我们得到:
$git reset HEAD stagedFile
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree