第一块失败了,位置在1。这是什么意思?

75

运行make时出现以下错误,我不知道它的含义或该如何处理。有人能为我解释一下或指点我吗?

(cd libdvdnav-git && patch -p1) < ../../contrib/src/dvdnav/dvdnav.patch
patching file Makefile.am
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file Makefile.am.rej
make: *** [dvdnav] Error 1

我正在尝试使用Linux将VLC交叉编译为Win32。


https://dev59.com/RH7aa4cB1Zd3GeqPo1jt - Bernardo Ramos
9个回答

87

这是由patch生成的错误。如果您打开.patch文件,您会看到它被组织成一堆所谓的“hunks”段落。每个hunk标识旧版本和新版本中相应代码(按行号)的差异以及它们之间的相似性(“上下文”)。

如果一个hunk的相似性与原始文件不匹配,那么它可能会失败。当您看到此错误时,几乎总是因为您正在使用错误版本的补丁程序来修补代码。有几种方法可以解决这个问题:

  • 获取已包含补丁的更新版本的libdvdnav(最佳选项)。
  • 获取要打补丁的libdvdnav版本的.patch文件。
  • 手动打补丁。对于补丁中的每个块,尝试定位libdvdnav中相应的文件和行,并根据补丁中的说明进行更正。
  • 使用与.patch文件所针对的版本较接近的libdvdnav版本(可能不是一个好主意)。

谢谢。因为我正在交叉编译并使用一个大脚本来获取库,所以我认为我宁愿编辑补丁文件。您能告诉我带有 @@ 符号的那行的含义吗? - JellicleCat
2
你的补丁是用统一格式的。忽略第二个@@后面的部分,在两个@@之间有两个术语:-l,s表示原始文件中块的偏移量(l是行号)和大小(s是行数),而+l,s则表示打补丁后文件中块的偏移量和大小。当有多个块时,通过手动确定+l,s部分可能需要相当多的工作。 - user824425

32

在某些情况下,文件版本之间没有区别,但仅存在缩进、空格、换行符或行号等差异。

为了尽管存在这些差异也能打补丁,可以使用以下两个参数:

--ignore-whitespace:它忽略空格差异(缩进等)。

--fuzz 3:“--fuzz X”选项将最大模糊因子设置为行。此选项仅适用于上下文和统一的 diff;它会忽略多达X行,同时寻找安装一个 hunk 的位置。请注意,更大的模糊因子会增加制作错误修补程序的可能性。默认的模糊因子是2;通常不需要将其设置为大于 diff 中上下文行数的值,即3。

不要忘记使用“--dry-run”:它会在不应用补丁的情况下尝试打补丁。

示例:

patch --verbose --dry-run --ignore-whitespace --fuzz 3 < /path/to/patch.patch

关于Fuzz的更多信息:

https://www.gnu.org/software/diffutils/manual/html_node/Inexact.html


遇到了同样的问题。也许只需要使用管道而不是复制。 - viggy28
这是我的问题。文件之间混合了制表符和空格。 - LFMekz
这解决了我编译 libecwj 的问题:patch --verbose --dry-run --ignore-whitespace --fuzz 3 -p1 < ../libecwj2-3.3-wcharfix.patch - robe007
1
代码块的顺序也很重要。如果它们所打的补丁代码在文件中出现在之前已经处理过的行之前(如果您刚刚新制作了补丁,则几乎不可能发生,但如果您正在使用后移版本,则不那么荒谬),则无论它们具有多大的模糊能力,都将失败。 - mirh

5

调试技巧

  1. 在补丁文件的末尾添加crlf,并测试其是否有效。
  2. 尝试使用--ignore-whitespace命令,例如: markus@ubuntu:~$ patch -Np1 --ignore-whitespace -d software-1.0 < fix-bug.patch 参见markus的教程

1
在我的情况下,补丁由IDEA完美生成,但是我编辑了补丁并保存它,这将CRLF更改为LF,然后补丁停止工作。奇怪的是,将其转换回CRLF并没有起作用。我注意到在VI编辑器中,即使设置为DOS格式,行末的'^M'也没有添加。这迫使我只能在VI中进行更改,以便保留EOL。
如果您在非Windows环境中对覆盖来自Windows环境的两个版本之间的更改的补丁进行更改,则可能适用于您。您需要小心编辑此类文件。
顺便说一句,ignore-whitespace没有帮助。

1
当我使用git diff生成补丁文件并粘贴输出时,出现了这种情况:
git diff branch-1 branch-2 # and then copy the output

这会插入或更改空格的性质。

我将输出重定向到文件中:

git diff branch-1 branch-2 > my-patch.patch

这解决了问题。


0

块 #1 在 1 处失败。 1 处中的 1 块失败 - 将拒绝保存到文件 Makefile.am.rej

当我通过补丁应用更改并完全在 StackOverflow 上搜索时,我发现了相同的错误,但我没有得到答案。

然后我搜索了一些小部分,比如补丁错误背后的原因,然后我发现了这个。

Hunk #n FAILED at nnn. n out of n hunks FAILED - saving rejects to file file.rej

这意味着一个或多个称为 hunks 的更改无法引入文件中。偶尔会出现这种情况,因为补丁是通过电子邮件或复制到文件中的,并且添加或删除了空格。尝试在命令行中添加 --ignore-whitespace 以解决此问题。

第二步

然后我搜索了文件的不同结尾,发现有两种格式系统 LF、CF

然后我使用以下命令检查我的文件格式

现在,如果此文件是在 *NIX 系统中创建的,则会显示

$ cat -A file
hello$

hello$

但如果这个文件是在Windows中创建的,它将会显示。

$ cat -A file
hello^M$

hello^M 

表示CR,$表示LF。请注意,Windows没有使用CRLF保存最后一行

我从StackOverflow上发现了这个问题。

然后我检查了我的原始文件格式以及.patch/diff文件,我发现补丁文件同时具有LF和Cf。

然后我通过使用dos2unix filename.extension或unix2dos filename.extension将这些文件转换为Windows或Unix格式之一,然后再应用补丁。

这会使文件发生变化,然后应用补丁来得到结果。

命令提示符命令

创建文件

touch filename.txt

创建一个补丁/差异文件
diff -u originalfile.txt editedfile.txt > originalfile.diff

或者

diff -u originalfile.txt editedfile.txt > originalfile.patch

在应用更改之前,请检查文件格式

cat -A originalfile.txt    
cat -A originalfile.diff

现在可以转换doc2unix或unix2dos

unix2dos originalfile.txt
unix2dos originalfile.diff

应用更改

patch originalfile.txt < originalfile.diff

完成了!!

希望这能对你有所帮助!


0

按照这里的说明操作,它解决了我的问题。

你需要像下面这样运行命令: patch -p0 --dry-run < path/to/your/patchFile/yourPatch.patch


0

当我在相关的git项目的顶级目录之外应用补丁时,我收到了“hunks failed”消息。我是在子目录中应用补丁(我创建它的地方)。

似乎可以在git项目的子目录中创建补丁,但无法应用。


1
这不是真的。但是,当使用patch时,您需要提供一个“-p”参数来告诉它应该忽略路径的前几部分。Patch不知道存储库,而git am知道。 - JonnyJD

0
请确保在制作差异文件之前,要比较的两个文件末尾没有多余的换行符

光标会停留在文件中最后一个输入的单词后面。


就OP正在编译其他人制作的软件而言,他们自己构建补丁的可能性非常小。除此之外,您有没有证据表明这是他们遇到的特定问题,而不仅仅是补丁与其试图应用的源之间几乎无限数量的不匹配方式之一? - Charles Duffy

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