无法在 git status 命令执行后使用 git merge --abort 命令

18

首先我合并了一些内容,然后出现了冲突,所以我运行了git merge --abort,但失败了,我不得不先运行git status,然后git merge --abort成功了。


$ git merge features/test
Auto-merging src/cmd.c
CONFLICT (content): Merge conflict in src/main.c
Auto-merging src/client.c
Automatic merge failed; fix conflicts and then commit the result.
$ git merge --abort
error: Entry 'src/option.h' not uptodate. Cannot merge.
fatal: Could not reset index file to revision 'HEAD'.
$ git merge --abort
error: Entry 'src/option.h' not uptodate. Cannot merge.
fatal: Could not reset index file to revision 'HEAD'.
$ git status 
# On branch te
# You have unmerged paths.
#   (fix conflicts and run "git commit")
#
# Changes to be committed:
#
**********
#
# Unmerged paths:
#   (use "git add <file>..." to mark resolution)
#
**********
#
$ git merge --abort
$ git status
# On branch te
nothing to commit, working directory clean

我有什么做错的吗?

git 版本 1.8.3.1


git版本2.21.0(Apple Git-122.2)。我也遇到了这个问题,git status也是解决方法。 - bshirley
6个回答

6

首先,我们需要运行

git status

然后

git merge --abort

5
运行此命令将会丢失尚未提交的更改!
git reset head

git checkout -- .

了解更多关于 git reset head 如何运作请点击 这里


3
注意:即使升级Git也可能不足够,在Git 2.19(2018年Q3)之前,例如在存在索引中有冲突的条目,以及涉及到D/F冲突的特定顺序时,"git merge --abort"等命令并不能完全清理掉这些问题。
这个问题已经在Git 2.19中得到了解决。
请参见ad37620提交记录25c200a提交记录(由Elijah Newren (newren)于2018年7月31日提交)。
(由Junio C Hamano -- gitster --8ba8642提交记录中合并,于2018年8月17日)

read-cache: fix directory/file conflict handling in read_index_unmerged()

read_index_unmerged() has two intended purposes:

  • return 1 if there are any unmerged entries, 0 otherwise
  • drops any higher-stage entries down to stage #0

There are several callers of read_index_unmerged() that check the return value to see if it is non-zero, all of which then die() if that condition is met.

For these callers, dropping higher-stage entries down to stage #0 is a waste of resources, and returning immediately on first unmerged entry would be better.
But it's probably only a very minor difference and isn't the focus of this series.

The remaining callers ignore the return value and call this function for the side effect of dropping higher-stage entries down to stage #0.
As mentioned in commit e11d7b5 ("'reset --merge': fix unmerged case", 2009-12-31, Git 1.7.0),

The only reason we want to keep a previously unmerged entry in the index at stage #0 is so that we don't forget the fact that we have corresponding file in the work tree in order to be able to remove it when the tree we are resetting to does not have the path.

In fact, prior to commit d1a43f2 ("reset --hard/read-tree --reset -u: remove unmerged new paths", 2008-10-15, Git 1.6.0.4), read_index_unmerged() did just remove unmerged entries from the cache immediately but that had the unwanted effect of leaving around new untracked files in the tree from aborted merges.

So, that's the intended purpose of this function.

The problem is that when directory/files conflicts are present, trying to add the file to the index at stage 0 fails (because there is still a directory in the way), and the function returns early with a -1 return code to signify the error.

As noted above, none of the callers who want the drop-to-stage-0 behavior check the return status, though, so this means all remaining unmerged entries remain in the index and the callers proceed assuming otherwise.

Users then see errors of the form:

error: 'DIR-OR-FILE' appears as both a file and as a directory
error: DIR-OR-FILE: cannot drop to stage #0

and potentially also messages about other unmerged entries which came lexicographically later than whatever pathname was both a file and a directory. Google finds a few hits searching for those messages, suggesting there were probably a couple people who hit this besides me.
Luckily, calling git reset --hard multiple times would workaround this bug.

Since the whole purpose here is to just put the entry temporarily into the index so that any associated file in the working copy can be removed, we can just skip the DFCHECK and allow both the file and directory to appear in the index.
The temporary simultaneous appearance of the directory and file entries in the index will be removed by the callers by calling unpack_trees(), which excludes these unmerged entries marked with CE_CONFLICTED flag from the resulting index, before they attempt to write the index anywhere.


如果遇到问题,可以使用git fsck命令进行排查:
在Git 2.28(2020年第三季度)之前,“git fsck”中用于确保树对象已排序的检查仍存在无法检测到未排序条目的特殊情况。

参见由René Scharfe (rscharfe)于2020年5月21日提交的fe747043d71b1cfc12aa78671559等提交。
(由Junio C Hamano -- gitster --于2020年6月9日合并,7e75aeb

fsck:检测更多树内目录/文件冲突

Signed-off-by: René Scharfe

(D/F:Directories/Files,即目录和文件)

如果堆栈顶部的冲突候选文件名不是当前冲突候选目录的前缀,则可以将其丢弃,因为后面不可能出现匹配的目录。

但是我们还没有完成对冲突候选目录的检查——堆栈中可能仍然存在匹配的文件名,因此请继续循环检查下一个冲突候选文件名。


我在 git version 2.21.0 (Apple Git-122.2) 中遇到了错误。 - bshirley
@bshirley 奇怪。这值得独立研究,以查看此错误是否来自相同的情况。此外,它是否会在 Git 2.25 中持续存在? - VonC

3

我做的有什么不对吗?

没有问题:应该可以在运行git status之前,使用git merge --abort成功。请为您正在使用的Git版本报告错误。编辑:1.8.3.1版本太老了,尽可能升级。


2

我不确定是否遇到了相同的问题,但当我运行git status时,它显示我有2个文件的消息是“Changes not staged for commit:”。

我想要回滚整个合并过程,所以我决定使用git restore放弃这两个文件的更改。然后我就能够中止合并了。

简而言之:

git restore path/name/of/file/to/restore

git merge --abort

1
在我的情况下,git status 没有帮助,但在提交本地更改后它愿意中止。
我的 git 版本:v2.25.0.windows.1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接