Git 应用跳过补丁

Git apply skips patches

我正在尝试应用包含带有 git apply 的二进制文件的补丁,但只添加了文件。我试过 运行 git apply failing.patch -v 并且它打印出如下内容:

Skipped patch 'file.txt'.
Checking patch file.bin...
Applied patch file.bin cleanly.

如何找出跳过的原因?由于目前的消息不是很有启发性。

我通过 运行 patch -p1 < failing.patch 发现了问题,它打印了:

can't find file to patch at input line 5

并提醒我我不在根目录中。

我不明白为什么 no one had asked this before 以及为什么详细消息不详细。

此外,甚至 official documentation 也没有提到跳过和可能的原因。

在尝试跨项目移植更改时遇到此问题。 git apply 似乎忽略了补丁文件路径上的任何目录名称,如果索引行与目标存储库中的文件哈希不匹配,它也拒绝应用。我使用这些选项取得了更好的成功(其中 --no-index 似乎没有记录):

git apply --verbose --no-index --directory {subdir} {patch-file} 

遇到了同样的问题。在我的例子中,错误来源是补丁目标的某些父目录中的 .git 文件夹。解决方案是将补丁目标移到该父目录之外。

如果您使用 --directory 选项“git apply”:

--directory=<root>

该路径 相对于基本目录(包含“.git”的目录),而不是相对于当前工作目录。您也不能使用绝对路径。

这完全没有记录,我花了几个小时才发现。

我根据此处的其他答案整理了一个解决方案,但仍需要做一些研究。 post 与其他人类似,但填补了我从其他人那里遗漏的部分。希望它能节省一些时间。

就我而言,与源代码库相比,目标代码库中有一个额外的目录级别。换句话说,源仓库中的顶级文件夹 source-top-level 包含在目标仓库中的父文件夹 target-top-level 中。但是,由于没有错误,我不能确定是不是问题所在。所以我使用了 --verbose,它显示了错误,我可以确认确实是问题所在。

然后我检查了 git 文档中的 --directory 选项。它允许您指定一个字符串,该字符串将添加到补丁中每个文件的路径中:

--directory=<root>
 Prepend <root> to all filenames.

通过指定 --directory=target-top-level,它将每个路径 source-top-level/some-path 转换为 target-top-level/source-top-level/some-pathgit apply 成功。