Answers:
因为没有意义(其他命令已经提供了该功能),并且减少了意外执行错误操作的可能性。
只需执行“硬重置”路径git checkout HEAD -- <path>
(检出文件的现有版本)。
路径的软复位没有意义。
路径的混合重置是做什么的git reset -- <path>
。
git checkout -- <path>
不进行硬重置;它用暂存内容替换工作树内容。git checkout HEAD -- <path>
对路径进行硬重置,将索引和工作树都替换为HEAD提交中的版本。
reset --hard
一条路径可以提供这个缺失的部分。Git已经非常强大,以至于“我们不允许您为了自己的保护而这样做”的借口是零水:有很多方法可以“无意间”做错事。无论如何,这都不重要git reflog
。
git reset --hard -- <path>
。有合法的用例。
问题如何已经回答,我将解释为什么部分。
那么,git reset有什么作用?根据指定的参数,它可以做两件事:
如果指定路径,它将用提交中的文件替换索引中匹配的文件(默认为HEAD)。这个动作根本不影响工作树,通常用作git add的反义词。
如果未指定路径,它将当前分支头移至指定的提交,并与一起将索引和工作树重置为该提交的状态。此额外的行为由mode参数控制:--
soft:不要触摸索引和工作树。
--mixed(默认):重置索引,但不重置工作树。
--hard:重置索引和工作树。
还有其他选项,请参阅文档以获取完整列表和一些用例。
当您不指定提交时,它默认为HEAD,因此git reset --soft
不会执行任何操作,因为这是将头移到HEAD(到当前状态)的命令。git reset --hard
另一方面,由于其副作用,它很有道理,它表示将head移至HEAD 并将索引和工作树重置为HEAD。
我认为现在应该很清楚为什么此操作不是针对特定文件的性质-它旨在首先移动分支头,重置工作树,而索引是第二功能。
git checkout
命令使用?并使重置执行相同的操作会使用户进一步困惑。我的回答是,该--hard
选项不适用于特定文件,因为它是分支重置而不是索引重置的模式。工作树重置称为结帐,您可以在其他答案中阅读。所有这些只是Git用户界面恕我直言的错误设计。
git checkout
:git reset --
仅设置索引,而仅git checkout --
设置工作树?
确保在原始或上游(源)与实际分支之间加上斜线:
git reset --hard origin/branch
要么
git reset --hard upstream/branch`
有背后的一个很重要的原因:原则checkout
和reset
。
用Git术语来说,检出意味着“进入当前的工作树”。并且,git checkout
我们可以用任何区域的数据填充工作树,无论是来自存储库中的提交的数据,还是来自提交或暂存区域的单个文件(甚至是默认值)。
反过来,git reset没有这个角色。顾名思义,它将重置当前引用,但始终将存储库作为源,而与“范围”(--soft,-mixed或--hard)无关。
回顾:
因此存在一个令人困惑的问题,git reset COMMIT -- files
因为仅用某些文件进行“覆盖HEAD”是没有意义的!
在没有官方解释的情况下,我只能推测git开发人员发现这reset
仍然是丢弃对暂存区所做的更改的命令的最佳名称,并且鉴于唯一的数据源是存储库,因此“ 让我们扩展功能 ”,而不是创建新命令。
因此,某种程度上git reset -- <files>
已经有些特殊了:它不会覆盖HEAD。恕我直言,所有这些变化都是例外。即使我们可以构思一个--hard
版本,其他版本(例如--soft
)也没有任何意义。
git reset -- <files>
由于它是一项有用的功能,所以喜欢添加它,但是没人知道应该在哪个命令中使用它。幸运的是,现在我们有更多的理智git restore
,其具有的功能git checkout -- <path>
git checkout <commit> -- <path>
和git reset [<commit>] -- <path>
使用更加健壮的默认值,甚至更多的功能,你以前无法完成(相反的是接受的答案说,现在你终于可以轻松地恢复只是工作树,没有动人的指数)。
该git reset
手册列出了三种调用方式:
2是文件方式的:它们不会影响工作树,而是仅对由<paths>
以下指定的索引中的文件进行操作:
git reset [-q] [<tree-ish>] [--] <paths>..
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
1是明智的提交方式:对引用的中的所有文件进行操作<commit>
,并且可能会影响工作树:
git reset [<mode>] [<commit>]
没有调用模式只能在指定的文件上运行并影响工作树。
如果两者都想:
您可以在git配置文件中使用此别名:
[alias]
reco = !"cd \"${GIT_PREFIX:-.}\" && git reset \"$@\" && git checkout \"$@\" && git status --short #" # Avoid: "fatal: Cannot do hard reset with paths."
然后,您可以执行以下操作之一:
$ git reco <paths>
$ git reco <branch/commit> <paths>
$ git reco -- <paths>
(用于reco
:re
set && c
heck o
ut)
git checkout -- <path>
应该替换为git reset --hard <path>
。这更有意义……