git status 显示现有文件已被删除

Wmb*_*uch 5 git

运行时git status我看到许多标记为的文件deleted

On branch my-branch
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    deleted:    nta/executor/.gitignore
    deleted:    nta/executor/NTA_EXECUTOR_README.md
    deleted:    nta/pom.xml
    ...
Run Code Online (Sandbox Code Playgroud)

尽管这些文件仍然存在于文件系统中。例如,我尝试使用建议的方法取消暂存这些更改

On branch my-branch
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    deleted:    nta/executor/.gitignore
    deleted:    nta/executor/NTA_EXECUTOR_README.md
    deleted:    nta/pom.xml
    ...
Run Code Online (Sandbox Code Playgroud)

这对某些文件有效,但许多其他文件仍列为deleted.

许多其他 SO 问题描述了类似的问题:

但其中描述的方法并没有解决我的具体问题。我努力了

git restore --staged nta/executor/.gitignore
Run Code Online (Sandbox Code Playgroud)

没有运气。还有其他想法吗?


此外

如果有帮助的话,这里是我为到达这里所做的可能愚蠢的事情的描述:

我想暂存多个foo在不同目录中调用的文件:

git reset <file>
git reset --hard <file>  # fatal: Cannot do hard reset with paths.
git reset -- <file>
git checkout -- <file>
Run Code Online (Sandbox Code Playgroud)

这最终增加了foo比我预期更多的 s 。所以我试图回溯:

git add */*/foo
Run Code Online (Sandbox Code Playgroud)

突然间,大量非foo文件被列为deleted

(现在你知道故事的其余部分了)

tor*_*rek 6

根据评论,您的 Git 版本中可能存在某种错误。一个简单的git reset(根本没有参数)应该可以解决这个问题,但实际上你必须先删除索引文件,然后重置:

\n\n
rm .git/index\ngit reset\n
Run Code Online (Sandbox Code Playgroud)\n\n

git reset将从头开始重新构建索引文件,因为它已经丢失了。 这应该是不必要的。 (另请注意,索引文件的位置取决于这是否是从git worktree add;上面假设不是。)

\n\n

(造成这种情况的一个潜在原因是 Windows 具有拒绝让程序写入文件的模式。1但这 在运行时应该显示为错误git reset。它还可能阻止删除文件,在这种情况下rm .git/index会失败也是。所以根本不清楚这里发生了什么。)

\n\n

原答案如下。

\n\n
\n\n

1 Windows 有一种叫做“强制文件锁”的东西。程序无法避免这些锁。尽管有些 Linux 文件系统具有额外的功能,但Linux 通常仅具有建议性文件锁定。例如,请参阅如何使 Windows 文件锁定更像 UNIX 文件锁定?

\n\n
\n\n

正如马特在评论中所说,这意味着您已经让 Git 删除了这些文件的索引副本。因此,将HEAD提交与建议的下一次提交进行比较,差异将是\xe2\x80\x94如果您现在实际提交\xe2\x80\x94这些文件将不会出现在下一次提交中,即在这两次提交之间,您已删除这些文件。

\n\n

要放回一个文件,请按照git status打印的说明进行操作:

\n\n
\n
  (use "git restore --staged <file>..." to unstage)\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

即,运行:

\n\n
git restore --staged nta/executor/.gitignore\n
Run Code Online (Sandbox Code Playgroud)\n\n

HEAD副本复制nta/executor/.gitignore回 Git 的索引中。现在该HEAD副本与索引的建议下一次提交副本匹配,并且git status将不再提及该文件。根据需要对每个文件重复此操作。

\n\n

如果您愿意,可以使用以下命令整体覆盖当前提交中的整个索引(整个建议的下一次提交):

\n\n
git reset\n
Run Code Online (Sandbox Code Playgroud)\n\n

(或git reset --mixed, but--mixed是默认值)。

\n\n

如果您已小心地将某些特定文件复制到索引中,这将覆盖索引中该仔细复制的文件,并且您可能必须再次小心地重新复制它,才能获得您如此仔细设置的效果。但通常,我们倾向于将工作树中的所有内容复制到索引中,因此以这种方式清除索引副本并不是什么大问题。

\n\n
\n

我尝试使用建议的方法取消暂存这些更改...这对某些文件有效,但许多其他文件仍被列为已删除。

\n
\n\n

我们可以对此使用更多细节,例如前后git status(或其部分)和所选git restore命令的实际剪切和粘贴。它绝对应该回到HEAD提交时的状态,之后git status应该保持安静。

\n