【问题标题】:Why is GNU patch failing for this diff?为什么 GNU 补丁在这个差异上失败了?
【发布时间】:2009-10-30 20:01:07
【问题描述】:

生日,

编辑:只是想我会提到这个有点长的问题现在已经解决,这要感谢 Adam Goode 在下面的回答,如果您只是在经过时略读。

我已经获得了一个要添加到 Apache 2.2.14 的补丁,而一个统一的差异根本没有修补该文件。我正在使用 GNU 补丁 2.5.4。

我必须忽略空格,因为原始补丁制作得不好,即许多差异似乎是用于制表符-> 空格转换。这些类型的差异甚至不太有用,因为补丁文件已在交付链中的某个地方被修改,例如svn 仓库、Jira 系统、web 界面等,让所有的 tab 反正都转成空格了!

我在 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 手册中的relevant paragraph for fuzz。

编辑 2: 顺便说一句,该模糊段落的底部有一个高度相关的警告:

patch 通常会产生正确的结果,即使它必须进行多次猜测。但是,只有将补丁应用于生成补丁的文件的精确副本时,才能保证结果。

不幸的是,在这种情况下,我无法确定他们的 mod_cache.h 是否与官方的 2.2.14 mod_cache,h 相同! )-:

【问题讨论】:

  • 看来成功了...?
  • @bdonian 它没有成功,伙计。从 DEFAULT_CACHE_MAXAGE 开始的四个宏不在最终文件中。
  • ...评论也没有改变。
  • @Jonathan,是的。很好发现,我很担心我没有看到的宏。

标签: c patch unified-diff


【解决方案1】:

当你使用--ignore-whitespace 而不使用--fuzz=0 时,你基本上是在告诉patch 它应该尽力修补,而不是完全失败。因为这是尽力而为,所以真的没有办法保证它会完美地工作。出于这个原因,git 和 Fedora RPM 默认设置为--fuzz=0,这样这些类型的问题会在补丁时(而不是编译时或运行时)失败。

如果您想将文件保存为 upstream-tarball + 补丁,您应该重做补丁并确保它可以通过--fuzz=0 应用。

【讨论】:

  • @Adam,感谢您的回答。 +1!不幸的是,我无法控制补丁的生成。更糟糕的是,创建补丁的人正在使用他们认为的 Apache v2.2.14 作为基准,他们自己在独立维护的源代码树上应用了一系列补丁!看起来他们自 2.2.9 以来一直在这样做。他们似乎不想确保他们与 Apache org 参考一致。 )-:
猜你喜欢
  • 1970-01-01
  • 2019-09-07
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 2014-01-05
  • 2011-08-08
相关资源
最近更新 更多