当git-am失败并出现“在索引中不存在”的错误时应该怎么办?

25

我有一个补丁,使用git am尝试应用它时会输出以下内容:

Checking patch old/filename...
error: old/filename: does not exist in index

在这个补丁中,old/filename实际上被移动到了new/filename, 但原始文件似乎已经从源代码树中消失了。

那么这个错误是什么意思以及如何解决或解决它?是否可以忽略它(使用--reject或其他方式)?

4个回答

7
补丁没有针对正确的源代码树创建。
可能发生这种情况的一种方式是:
假设您要应用补丁的原始分支具有提交历史:
1a -> 1b -> 1c -> 1d
然后克隆了该分支,并进行了新的提交:
1a -> 1b -> 1c -> 1d -> 1e 提交1e包含old/filename文件。
现在,您在第二个分支上进行了补丁工作,而不是在原始分支上:
1a -> 1b -> 1c -> 1d -> 1e -> 1f
提交1f包含了重命名old/filename为new/filename的更改。
现在,如果您为提交1f创建一个补丁,则无法将其应用于提交1d之上,因为缺少添加old/filename到索引/存储库中的提交1e。

你可以快速双重检查一下git抱怨的文件是否仍然存在。我刚遇到了这个问题,而git抱怨的文件实际上已经被我的同事移动了,因此出现了这个问题。Git cherry-pick在处理这种问题方面更加智能,对我非常有效(但你需要逐个提交)。 - user3613932
那么根据问题,他应该怎么做呢? - anaval

2
你可以使用--reject命令让它尽力处理并将其余部分输出到.rej文件中。然后你可以手动修复并提交。
提示来自:Raymes Khoury

--reject 选项不能用于找不到文件的情况。只有在补丁无法应用但文件存在的情况下才能使用。 - Julien

1
"git am"命令没有给出非常清晰的失败位置。我尝试了以下操作:使用“patch -p n patch_file”进行尝试。这个Unix“patch”命令清楚地显示了拒绝发生的位置。如果patch命令可以工作,那么补丁文件就是好的。
我看到“patch -p n”命令起作用了,但“git am -p n”仍然失败,并显示模糊和混乱的错误消息“不存在于索引中”。我怀疑它只是找不到正确的文件。所以我将n调整为n-1。然后它就起作用了。
因此,实际原因是-p参数应该使用n-1,其中n是“patch”命令的正确参数。
简而言之,可行的命令是“git am -p n-1 patch_file”。

0

遇到了类似的问题,想要将一个仓库中的补丁应用到另一个仓库中,但是两个仓库之间有不同的提交记录,就像Jacques在这里所描述的那样:https://dev59.com/IGIk5IYBdhLWcg3wn_VF#27998109

需要注意的是,我尝试应用补丁的文件没有被移动(相对路径相同)。 解决方法是使用“三方合并”,就像这里建议的那样:https://dev59.com/CWQo5IYBdhLWcg3wR9nD#16968982

git am -3 < changes.patch

通过Matt在类似问题上的评论找到了这个方法:How can I generate a Git patch for a specific commit?


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