git 隐藏由于错误排序的参数和丢失的未跟踪文件而导致的部分失败

git stash partial failure due to wrongly ordered arguments and lost untracked files

我有一些修改过的文件,还有 2 个未跟踪的文件。

我想隐藏一些修改和未跟踪的文件 我想隐藏的所有想法都在同一个目录中,所以我使用它和末尾的通配符来实现隐藏其中的所有文件。

所以我运行

git stash push -u  -- File/Path/To/FolderOfFilesIWantCommited/* -m "My Message"

这返回了这个

Saved working directory and index state WIP on [Branch Name]: [Commit Sha1] [commit message]
fatal: pathspec '-m' did not match any files
error: unrecognized input

这条消息就是我在标题中说 'partial failure' 的原因..目前还不清楚这里发生了什么

我意识到我应该运行是

git stash push -u -m "My Message"  -- File/Path/To/FolderOfFilesIWantCommited/* 

然而,在第一次尝试失败后,我的所有修改仍然未暂存但存在。然而,2 个未跟踪的文件已经消失。我真的可以用它们回来,所以任何帮助将不胜感激

只是补充说明:我 运行 在 Powershell 中使用 PoshGit,这是一条或多条错误消息的原因。我想我会把它包括在内,因为它可能会让其他人感到困惑

TL;DR:您 运行 发现了 commit 833622a945a6, "stash push: avoid printing errors", which first appeared in Git 2.18.0. If your Git is at least 2.16.2, you're OK, otherwise you may have run into the rather more severe bug fixed in commit bba067d2faf0, "stash: don't delete untracked files that match pathspec" 中已修复但从未在发行说明中提及的错误。

接受路径规范的push子命令最早出现在Git 2.13.0。如果 运行 来自子目录,直到它在 2.13.2 / 2.14.0 中被修复之前,它已经完全崩溃了。而且,它在 2.16.2 之前表现不佳:它可能 运行 git clean 处理太多文件。由于 git clean 删除 未跟踪的 文件(可选地包括这些文件的忽略子集),并且未提交未跟踪的文件(特殊 -u / -a commit),此时它们可能只是 gone

如果你没问题——如果你的 Git 至少是 2.16.2,我认为是——忽略投诉; git stash pop 存储并重新 运行 带有更正参数的命令,以按照您要求的方式命名存储。否则,被 git clean 错误清除的文件根本无法通过 Git 恢复(但我认为,考虑到我认为你 运行 加上错误消息,你没问题)。

(我建议在大多数情况下避免巧妙地使用 git stash——通常只进行临时提交会更好。您还将避免被这些类型的错误绊倒。)

首先,快速附注:git stash 所做的是进行(或使用)提交,特别是两次(常规存储)或三次(stash -ustash -a)提交在 nob运行ch 上。这两个或三个提交持有:

  • 索引状态;
  • 工作树状态;
  • 任何未跟踪的文件,如果使用 -u-a

git stash push,以及它的一些错误

git stash push -u  -- File/Path/To/FolderOfFilesIWantCommited/* -m "My Message"

[然后失败]

Saved working directory and index state <msg>
fatal: pathspec '-m' did not match any files
error: unrecognized input

这是有道理的,因为--表示选项结束,之后所有字符串被当作路径名或路径规范(路径名的概括,其中* 之类的意思是 "all files")。在这种情况下,您给了 Git 这三个路径规范:

  • File/Path/To/FolderOfFilesIWantCommited/*
  • -m
  • My Message

这些是 Git 应该在提交时保存的特定文件。由于在一般情况下,任何提交都会保存 每个 (跟踪的)文件,因此这里有一些奇怪的皱纹。我们几乎可以忽略这个事实——虽然 git stash save 仍然保存两个主要提交中的每个跟踪文件,路径规范所做的是告诉 git stash 哪个版本 保存在工作树提交中:它应该保存 work-tree 版本,还是 index 版本?如果 pathspec 匹配匹配跟踪文件,则工作树版本是保存的版本;否则索引版本是保存的版本。 (索引提交仍然像往常一样保存所有索引内容,因为它们在您 运行 git stash,使用 git write-tree 时。)

这是第三次提交,由 -u-a 完成,其中路径规范在这里对您最重要:它将提交限制为仅包含 匹配的未跟踪文件,而不是所有未跟踪(并且可能被忽略,-a)文件。这也是令人讨厌的错误出现的地方:在提交中保存文件内容后,git stash 运行s,本质上是 git reset --hardgit clean,以设置索引和工作树状态恢复到原来的状态,并删除额外提交中保存的文件。

我相信 2.16.2 中添加的修复是导致 2.18.0 中修复的投诉的原因。如果是这样,这意味着您的 git stash push 没有清除太多文件;相反,它清理了正确的文件——那些保存在第三次提交中的文件——然后抱怨,因为你的路径规范只匹配未跟踪的文件 and/or,因为额外的参数匹配 no 文件。

在极端情况下,如果你只想在第三次"u"提交中获取文件而不使用git stash,请考虑运行宁git show stash^^3 | git apply(注意:这是 git show stash,第一个词是 show,而不是 git stash show!)。 git stash 进行的第三次提交是 refs/stash 的第三次提交,因此 stash^3。在 PowerShell 中,我相信这必须用双倍 ^ 来编写。您可以运行 git show stash^^3(同倍加倍)查看后再应用。