【问题标题】:Why does `git reset --hard HEAD~X` leave untracked files behind?为什么 `git reset --hard HEAD~X` 会留下未跟踪的文件?
【发布时间】:2018-02-28 06:29:51
【问题描述】:

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

当我运行 git reset --hard HEAD 时,它应该重置为 据我了解,您所提取的原始版本。 不幸的是,它会留下文件,因为git status 显示了 未跟踪文件的大列表。

你如何告诉 git“只要把它恢复到最后一次拉取的内容,仅此而已,仅此而已”?

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

谁能解释一下为什么它会这样工作以及哪些文件会变得无法追踪?

【问题讨论】:

  • 因为 git 非常非常小心,不会破坏它无法恢复的工作(它对它一无所知的工作)。由于这些文件未跟踪,git 无法返回到它们的早期版本,因此将它们单独用于结帐、重置等日常操作。“将其恢复到最后一次提取”重点是:您知道 - 作为阅读目录列表的人 - 项目状态是什么,但 git 不知道,因为未跟踪的文件是 untracked
  • 所以所有在 HEAD~X 提交中不存在的文件,都将变得不被跟踪?
  • 不,在 HEAD 中跟踪但不在 HEAD~X 中的文件也将被删除。

标签: git git-reset


【解决方案1】:

更新每个 cmets 中的注释。

最后一个问题:

哪些文件将无法跟踪?

没有。但是已经未跟踪的文件应保持未跟踪且不受影响。这与大多数 git 命令的行为一致(那些显式影响未跟踪文件的命令除外)。

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

有人能解释一下为什么会这样吗[?]

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

那么回到原来问题的前提:

当我运行 git reset --hard HEAD 时,据我所知,它应该重置为您拉取的原始版本

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

【讨论】:

  • “但是已经被追踪的文件将保持未被追踪并且不会受到影响。” – 只有 iff 他们在你的提交中也未被追踪正在重置。
  • @poke - 是的,不幸的是,在您跟踪文件、删除文件但保留(或重新引入)工作树副本的不寻常情况下,git 会覆盖工作树版本。如果您意识到该文件不属于源代码管理并因此将其添加到 .gitignore 并将其从索引/后续提交中删除,这很可能是一个问题。相对于文档,我将其解释为一个错误;出错将是一种更好的行为。
【解决方案2】:

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

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

这意味着,通常情况下,被忽略的文件和新文件将被单独保留。

它的工作方式与 Git 处理跟踪/未跟踪文件的一般方式是一致的。对 Git 来说,未跟踪的文件是不可见的,Git 永远不会触及它们。当您检查一个之前未跟踪(但存在)的文件被跟踪的分支时,情况也是如此:Git 将拒绝这样做,因为未跟踪文件的状态将会丢失。

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

【讨论】:

    猜你喜欢
    • 2011-05-18
    • 2018-07-02
    • 2014-08-25
    • 2018-01-13
    • 2019-09-05
    • 2017-12-10
    • 2011-09-06
    • 1970-01-01
    相关资源
    最近更新 更多