在git状态之前无法进行git merge --abort [英] Cannot git merge --abort until git status

查看:406
本文介绍了在git状态之前无法进行git merge --abort的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先我合并,然后发生冲突,所以我git merge --abort,但是失败了,我必须先执行git status,然后git merge --abort成功.

First I merge sth, then conflicts occurs, so I git merge --abort, but failed, I have to do git status first, then git merge --abort succeeded.

$ 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可能还不够,直到Git 2.19(2018年第三季度),因为"git merge --abort"等无法正确清理东西.当索引中有某些顺序的条目涉及D/F冲突时.
Git 2.19已更正了该问题.

Note: even upgrading Git might not be enough, not until Git 2.19 (Q3 2018), since "git merge --abort" etc. did not clean things up properly when there were conflicted entries in the index in certain order that are involved in D/F conflicts.
This has been corrected with Git 2.19.

请参见提交ad37620 伊利亚·纽伦(newren).
(由 Junio C Hamano合并-gitster-

See commit ad37620, commit 25c200a (31 Jul 2018) by Elijah Newren (newren).
(Merged by Junio C Hamano -- gitster -- in commit 8ba8642, 17 Aug 2018)

read-cache:修复read_index_unmerged()

中的目录/文件冲突处理

read_index_unmerged()有两个预期目的:

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

read_index_unmerged() has two intended purposes:

  • 如果有任何未合并的条目,则返回1,否则返回0
  • 将所有较高级别的条目拖放到第0阶段

read_index_unmerged()的多个调用方检查返回 值以查看它是否为非零,如果满足该条件,则全部为die() 被满足.

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.

对于这些调用者,将较高级别的条目放到阶段#0会浪费资源,并且在第一个未合并的条目上立即返回会更好. 但这可能只是一个很小的差异,并不是本系列的重点.

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.

其余调用者忽略返回值,并调用此函数,以防将较高级的条目放到#0级的副作用.
commit e11d7b5 ('reset --merge':fix unmerged case" ,2009-12-31,Git 1.7.0),

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),

我们要在阶段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.

实际上,在提交d1a43f2 之前(重置--hard/read -tree --reset -u: 删除未合并的新路径",2008-10-15,Git 1.6.0.4),read_index_unmerged()只是 立即从缓存中删除未合并的条目,但是这样做会产生不良影响,即从中止的合并中在树中留下新的未跟踪文件.

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.

问题是当存在目录/文件冲突时,在阶段0尝试将文件添加到索引失败(因为途中仍然存在目录), 并且该函数会以-1的返回码提前返回,以表示错误.

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.

但是,如上所述,没有任何希望执行drop-to-stage-0行为的调用者会检查返回状态,因此,这意味着所有剩余的未合并条目仍保留在索引中,并且调用者会进行其他假设.

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

,还可能包含有关其他未合并条目的消息,这些消息在词典编排上比文件名和目录都晚. Google在搜索这些消息时发现了一些匹配项,这表明除我之外可能还有其他几个匹配项.
幸运的是,多次调用git reset --hard可以解决此错误.

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.

由于此处的整个目的是将条目临时放入索引中,以便可以删除工作副本中的任何关联文件,因此我们可以跳过DFCHECK并允许两者要显示在索引中的文件和目录.
调用者将通过调用unpack_trees()来删除索引中目录和文件条目的临时同时出现,这会在尝试将索引写入任何位置之前,从结果索引中排除这些带有CE_CONFLICTED标志的未合并条目.

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年第3季度)之前,检查"git fsck"以确保树对象已排序,但是仍然遗漏了未排序的条目.


In case of problem, git fsck can help:
Before Git 2.28 (Q3 2020), the check in "git fsck" to ensure that the tree objects are sorted still had corner cases it missed unsorted entries.

请参见提交fe74704 提交fc12aa7 提交8671559 (2020年5月21日),通过RenéScharfe(rscharfe).
(由 Junio C Hamano合并-gitster-

See commit fe74704, commit 3d71b1c, commit fc12aa7, commit 8671559 (21 May 2020) by René Scharfe (rscharfe).
(Merged by Junio C Hamano -- gitster -- in commit 7e75aeb, 09 Jun 2020)

fsck :检测到更多的树内d/f冲突

签名人:RenéScharfe

fsck: detect more in-tree d/f conflicts

Signed-off-by: René Scharfe

(D/F:目录/文件)

(D/F: Directories/Files)

如果从堆栈顶部开始的冲突候选文件名不是当前候选目录的前缀,那么我们可以将其丢弃,因为以后将找不到匹配的目录.

If the conflict candidate file name from the top of the stack is not a prefix of the current candiate directory then we can discard it as no matching directory can come up later.

但是我们还没有完成检查候选目录的工作-堆栈可能仍保留匹配的文件名,因此请继续循环并检查下一个候选文件名.

But we are not done checking the candidate directory -- the stack might still hold a matching file name, so stay in the loop and check the next candidate file name.

这篇关于在git状态之前无法进行git merge --abort的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆