为什么 `git reset --hard HEAD~X` 会留下未跟踪的文件?

Why does `git reset --hard HEAD~X` leave untracked files behind?

来自git reset --hard HEAD leaves untracked files behind

When I run git reset --hard HEAD, it's supposed to reset to a pristine version of what you pulled, as I understand it. Unfortunately, it leaves files lying around, as a git status shows a big list of untracked files.

How do you tell git "Just bring it back to EXACTLY what was in the last pull, nothing more, nothing less"?

要删除这些文件,我必须 运行 git clean -df

有人可以解释一下为什么它是这样工作的,哪些文件会变得无法跟踪?

git reset --hard 只会用您要重置的提交状态替换所有 当前跟踪的 文件。这具有以下效果:

  • 将删除对跟踪文件的所有未决更改。
  • 目标提交的跟踪文件的所有更改都将被删除。
  • 当前提交和目标提交均未跟踪的文件将保持原样。

这意味着,通常忽略的文件和新文件将被保留。

其工作方式与 Git 对 tracked/untracked 文件的一般操作方式一致。对于 Git,未跟踪的文件有点不可见,它们永远不会被 Git 触及。当您签出跟踪文件的分支时,这甚至是正确的,该分支之前未跟踪(但存在):Git 将拒绝这样做,因为未跟踪文件的状态将丢失。

Git 通常会非常努力地不丢失任何本地更改。通过说 git reset --hard 你实质上是在说“我知道这将消除你所知道的文件的所有未决更改,所以把它们扔掉”。但这不包括对本地未跟踪文件的任何声明,因此这些文件将保持原样。

根据评论中的注释更新

最后一个问题在先:

which files will become untracked?

None。但是 已经 未跟踪的文件应该保持未跟踪状态并且不会受到影响。这与大多数 git 命令的行为一致(明确影响未跟踪文件的命令除外)。

我说 应该 保持未跟踪,但是,因为有一种情况甚至不是这样:如果您要重置的提交在同一路径上有一个文件作为您当前未跟踪的文件,那么工作树版本将被不可逆转地破坏。这是非常不 git 的行为,IMO 是一个错误,但它确实存在。

Can somebody please explain why it works this way[?]

因为如果 git 隐式删除或修改未跟踪的文件,您将无法恢复该文件在 git 弄乱它之前的样子。如果您希望文件在 git 的控制下,git 假定您已经添加并可能提交了它。由于您没有(文件未被跟踪),git 通常不会弄乱它,除非您明确告诉它应该这样做。

所以回到原题的前提:

When I run git reset --hard HEAD, it's supposed to reset to a pristine version of what you pulled, as I understand it

没有。文档很清楚,只有跟踪状态被还原。