为什么这个 diff 的 GNU 补丁失败了?
-
22-07-2019 - |
题
你好,
编辑:只是想我会提到这个有点长的问题现在已经解决了,感谢亚当·古德(Adam Goode)在下面的回答,如果你只是在路过时略读的话。
我已经获得了一个要添加到 Apache 2.2.14 的补丁,但一个统一差异根本没有修补该文件。我正在使用 GNU 补丁 2.5.4。
我必须忽略空格,因为原始补丁制作得不好,即许多差异似乎是针对制表符 -> 空格转换。这些类型的差异甚至没有什么用处,因为补丁文件已经在交付链的某个地方被修改了,例如svn 存储库、Jira 系统、Web 界面等,这样所有制表符无论如何都已转换为空格!
我在 Solaris 10 上使用的命令是:
/usr/bin/gpatch --verbose --ignore-whitespace -p1 -d . \
<mod_cache.diff
输出是:
...
Hmm... The next patch looks like a unified diff to me...
The text leading up to this was:
--------------------------
|Index: httpd/modules/cache/mod_cache.h
|===================================================================
|--- httpd/modules/cache/mod_cache.h
|+++ httpd/modules/cache/mod_cache.h
--------------------------
Patching file modules/cache/mod_cache.h using Plan A...
Hunk #1 succeeded at 24.
Hunk #2 succeeded at 86.
Hunk #3 succeeded at 138.
Hunk #4 succeeded at 163.
Hunk #5 succeeded at 184.
Hunk #6 succeeded at 217.
Hunk #7 succeeded at 271.
Hunk #8 succeeded at 380.
...
注意
Hunk #2 succeeded at 86.
线。
补丁文件包含几个统一的差异,但相关的差异是:
...
Index: httpd/modules/cache/mod_cache.h
===================================================================
--- httpd/modules/cache/mod_cache.h
+++ httpd/modules/cache/mod_cache.h
@@ -86,9 +86,13 @@
#define DEFAULT_CACHE_MAXEXPIRE MSEC_ONE_DAY
#define DEFAULT_CACHE_EXPIRE MSEC_ONE_HR
#define DEFAULT_CACHE_LMFACTOR (0.1)
+#define DEFAULT_CACHE_MAXAGE 5
+#define DEFAULT_CACHE_LOCKPATH "/mod_cache-lock"
+#define CACHE_LOCKNAME_KEY "mod_cache-lockname"
+#define CACHE_LOCKFILE_KEY "mod_cache-lockfile"
-/* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and
- * PROXY_DECLARE_DATA with appropriate export and import tags for the platform
+/* Create a set of CACHE_DECLARE(type), CACHE_DECLARE_NONSTD(type) and
+ * CACHE_DECLARE_DATA with appropriate export and import tags for the platform
*/
#if !defined(WIN32)
#define CACHE_DECLARE(type) type
...
以及来源的相关部分, 应用补丁后 (据说)加上一些附加的上下文,是:
...
#define MSEC_ONE_DAY ((apr_time_t)(86400*APR_USEC_PER_SEC)) /* one day, in microseconds */
#define MSEC_ONE_HR ((apr_time_t)(3600*APR_USEC_PER_SEC)) /* one hour, in microseconds */
#define MSEC_ONE_MIN ((apr_time_t)(60*APR_USEC_PER_SEC)) /* one minute, in microseconds */
#define MSEC_ONE_SEC ((apr_time_t)(APR_USEC_PER_SEC)) /* one second, in microseconds */
#define DEFAULT_CACHE_MAXEXPIRE MSEC_ONE_DAY
#define DEFAULT_CACHE_EXPIRE MSEC_ONE_HR
#define DEFAULT_CACHE_LMFACTOR (0.1)
/* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and
* PROXY_DECLARE_DATA with appropriate export and import tags for the platform
*/
#if !defined(WIN32)
#define CACHE_DECLARE(type) type
#define CACHE_DECLARE_NONSTD(type) type
#define CACHE_DECLARE_DATA
#elif defined(CACHE_DECLARE_STATIC)
...
所有其他补丁似乎已成功应用或被忽略。
有什么想法为什么这个特定的差异没有被采用吗?
编辑: 按照 Adam 的建议将补丁模糊因子降低到零后,该补丁已成功运行。
感谢亚当·古德(Adam Goode),如果我能为你的答案再投一票,我会的!这是 模糊的相关段落 如果您有兴趣,请参阅 GNU diffutils 手册。
编辑2: 顺便说一句,在该模糊段落的底部有一个高度相关的警告:
patch 通常会产生正确的结果,即使它必须进行许多猜测。但是,只有当补丁应用到生成补丁的文件的精确副本时,结果才能得到保证。
不幸的是,在这种情况下,我无法确定他们的mod_cache.h与官方2.2.14 mod_cache,h相同!)-:
解决方案
当你使用 --ignore-whitespace
并且不要使用 --fuzz=0
, ,您基本上是在告诉 patch 它应该尽最大努力进行修补,而不是完全失败。因为这是尽力而为,所以确实没有办法保证它能完美地工作。为此,git 和 Fedora RPM 设置 --fuzz=0
默认情况下,这些类型的问题会在修补时(而不是编译时或运行时)失败。
如果您想将文件保留为上游 tarball + 补丁,您应该重做补丁并确保它可以应用 --fuzz=0
.