无法在合并过程中进行软重置,但没有要中止的合并

Cannot do a soft reset in the middle of a merge, but there is no merge to abort

提问人:Anton Strogonoff 提问时间:11/8/2023 最后编辑:Anton Strogonoff 更新时间:11/9/2023 访问量:59

问:

在错误地多运行了一次后,我遇到了合并冲突。我尝试使用不熟悉的(对我来说)Git 客户端解决它们,但没有完全成功,所以我决定手动退出合并并发现这是不可能的。git stash pop

在我停止摆弄不熟悉的 Git 客户端并直接在 CLI 中执行以下命令后,我决定发布这个问题,一个接一个,结果自相矛盾/矛盾:

$ git reset --soft HEAD
fatal: Cannot do a soft reset in the middle of a merge.

$ git merge --abort
fatal: There is no merge to abort (MERGE_HEAD missing).

附加信息:

  • git status显示一个“未合并的路径”,即“都已修改”
  • 运行已经解决了这种情况,现在我可以进行重置,并且不再有“未合并的路径”git restore --staged <that path>
  • 我的 Git 版本是 2.39.1

在这一点上,我的兴趣更多的是学术而不是实践:这是一种“这里没什么可看的,对 Git 提出一个关于自相矛盾的错误消息的错误”的情况,还是对 Git 的工作原理有一些需要理解的东西,可以深入了解正在发生的事情?

git git-merge

评论

1赞 knittl 11/8/2023
git reset(没有选项,没有提交)
1赞 Romain Valeri 11/8/2023
(或者,如果仍有未合并的条目。但当然,它不应该满足你在这里(理智的)好奇心。部分答案是,在未知的 UI 操作之后,您的索引一定是脏的,并且混淆了常用命令的输出。重置它就可以了。git reset --merge
0赞 Anton Strogonoff 11/8/2023
谢谢knittl和Romain。似乎我用另一种方式解决了这种情况,所以我不知道你的建议会有什么作用。不过,我很好奇,Git 存储库的什么奇怪的内部状态会导致它在一个命令中报告“在合并过程中”,但从另一个命令中报告“没有合并中止”。
0赞 Anton Strogonoff 11/8/2023
也许这个问题没有样本回购就毫无意义,我会看看我是否可以改天从头开始重现这种奇怪的状态......

答:

0赞 knittl 11/8/2023 #1

Git Reset 支持多种操作模式:

SYNOPSIS
       git reset [-q] [<tree-ish>] [--] <pathspec>...
       git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
       git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>...]
       git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

DESCRIPTION
       In the first three forms, copy entries from <tree-ish> to the index. In
       the last form, set the current branch head (HEAD) to <commit>,
       optionally modifying index and working tree to match. The
       <tree-ish>/<commit> defaults to HEAD in all forms.

您正在使用 执行最后一个表单,即:git reset --soft HEAD

   git reset [<mode>] [<commit>]
       This form resets the current branch head to <commit> and possibly
       updates the index (resetting it to the tree of <commit>) and the
       working tree depending on <mode>. Before the operation, ORIG_HEAD
       is set to the tip of the current branch. If <mode> is omitted,
       defaults to --mixed. The <mode> must be one of the following:

       --soft
           Does not touch the index file or the working tree at all (but
           resets the head to <commit>, just like all modes do). This
           leaves all your changed files "Changes to be committed", as git
           status would put it.

但是,您希望使用前三种形式之一来重置索引(重置所有暂存更改),使用:git reset

   git reset [-q] [<tree-ish>] [--] <pathspec>..., git reset [-q]
   [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
       These forms reset the index entries for all paths that match the
       <pathspec> to their state at <tree-ish>. (It does not affect the
       working tree or the current branch.)

评论

0赞 Anton Strogonoff 11/9/2023
谢谢,这阐明了软重置的作用;但问题是,为什么由于合并正在进行中而无法重置分支头,而由于没有合并正在进行而无法中止合并?那么合并冲突会不会是一个怪癖呢?stash pop
0赞 knittl 11/9/2023
@AntonStrogonoff只合并索引/工作树(并且不创建合并提交)。 合并分支(并创建合并提交)。两者都使用“合并”一词,但含义/上下文不同。stash popgit merge
1赞 j6t 11/9/2023 #2

该通知实际上只是一个最好的猜测,而不是一个精确的诊断。 这里可能不那么具体,因为它并没有花很多时间弄清楚准确的情况。in the middle of a mergegit reset --soft

当您在本地使用 Git 时,一个中心枢纽是“索引”(以前称为“缓存”),Git 在其中缓存它跟踪的工作树中的文件的状态。该索引还记录在“合并”操作期间发生冲突时的文件状态。

问题是,“mergy”操作不仅发生在由 启动的实际合并期间,还发生在许多其他操作期间。一个突出的此类操作是 。而且是另一个。git mergegit cherry-pickgit stash pop

接下来的事情是,当索引包含合并冲突的记录时,某些操作是不允许的。在这种情况下禁止的最重要的操作是 。而且,正如你所发现的,是另一个。对于这些操作,检查索引以了解操作是否可以继续或必须停止就足够了。当它们停止时,在假设正在进行的假设下,会发出您看到的错误。然而,他们实际上的意思是,你是.git commitgit reset --softa mergein the middle of a _mergy_ operation

git merge然而,这是一个更高级的操作。在发生冲突的情况下,它不仅会留下处于冲突状态的索引,而且还会留下用户最终使用或在解决冲突后结束合并时所需的其他状态。因此,有更多的线索来找出你是否真的处于“合并”之中;您观察到的特定问题是该文件不存在。git merge --continuegit commitgit merge --abortMERGE_HEAD