导致git-apply"腐败补丁的原因是什么?"

时间:2016-06-25 15:44:15

标签: git patch

(长篇故事......)

我正在将一个巨大的PHP应用程序带到本世纪...... ; - ) ...而其他团队正在继续维护它的现有版本

到目前为止,这已经导致大约275个补丁。问题是,我们所做的更改之一是将<?代码转换为<?php,并在整个代码中进行了一些类似的更改。当然,所有这些都阻止了应用补丁,因为(确实......)源代码没有匹配。

所以,我想编写一个小脚本来编辑补丁文件:更改补丁中的标签。

但我得到的是corrupt patch

所以,我想知道的是:导致这条消息是什么?也就是说,当它出现这个消息时,Git正在寻找什么样的错误?我需要&#34;调整我的调整器&#34; ... ahem ...以便编辑的补丁有效。 (N.B。原始补丁文件,在我调整它们之前,不是&#34;腐败,&#34;所以它必须是我正在做的事情。)

我的脚本正在尝试更改上述PHP标记和<?php echo以及一个函数名称。只不过是全球的preg-replace。我不会轻易看到我可以说的是什么,我们应该说,&#34;结构问题&#34;对Git。但是,显然,有些东西是。

示例补丁:corrupt patch at line 37 ...

From 342c5939da8cf4cbe495be7d635cd627bd2a44ed Mon Sep 17 00:00:00 2001
From: xxx <xxx@yyy.com>
Date: Wed, 17 Feb 2016 03:45:31 +0000
Subject: [PATCH 001/275] Make it all work 


---
 catalog/includes/modules/shipping/upsFreeGround.php | 2 +-
 catalog/product_info_v3.php                         | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/catalog/includes/modules/shipping/upsFreeGround.php b/catalog/includes/modules/shipping/upsFreeGround.php
index 45a6da4..55ccecb 100755
--- a/catalog/includes/modules/shipping/upsFreeGround.php
+++ b/catalog/includes/modules/shipping/upsFreeGround.php
@@ -194,7 +194,7 @@ function quote($method = '') {

         // Can probably combine this with the above, eventually
         $allFreeBW2016Plaques = false;
-           if (STORES_ID == 10) {
+           if ((STORES_ID == 10) || (STORES_ID == 26)) {
             $allFreeBW2016Plaques = true;
             foreach ($order->products as $aProduct) {
                    $thisNote = $aProduct['product_specific_notes'];
diff --git a/catalog/product_info_v3.php b/catalog/product_info_v3.php
index 09d88de..10d9b76 100644
--- a/catalog/product_info_v3.php
+++ b/catalog/product_info_v3.php
@@ -186,7 +186,7 @@ function doRequestComplete() {
        }
    }
 <?php -if ((STORES_ID == 10) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
+if (((STORES_ID == 10) || (STORES_ID == 26)) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
 function doCheckBW2016PlaqueProperty() {
    thePropertyNumber = document.getElementById('propertyToCheck');
    if (thePropertyNumber.value == "") {
@@ -1426,7 +1426,7 @@ if($combo_count>0) { ?>
                        ?>
                        </div> <!-- div_add_to_cart -->
            </div> <!-- cart_info_row2 -->
-           <?php if ((STORES_ID == 10) && (in_array( $products_id, $bwFreePlaqueIDList2016))) {
+           <?php if (((STORES_ID == 10) || (STORES_ID == 26)) && (in_array( $products_id, $bwFreePlaqueIDList2016))) {
                // First, let's see if we are "sold out"
                $query = "select bw_plaque_2016_id from bw_plaque_2016 where first_one_free='1' limit 1";
                $bwpRes = tep_db_query( $query);
@@ -1629,7 +1629,7 @@ DIVCONTAINER;
 </table> <!--pageTable for sure -->

 <script type='text/javascript'>
-   <?php if ((STORES_ID == 10) && (in_array( $products_id, $bwFreePlaqueIDList2016))) { ?>
+   <?php if (((STORES_ID == 10) || (STORES_ID == 26)) && (in_array( $products_id, $bwFreePlaqueIDList2016))) { ?>
    function doFreePlaquePriceChange() {
        // Change the quantity to 1
        $('quantityToAdd').setValue('1');
-- 
2.6.4 (Apple Git-63)

4 个答案:

答案 0 :(得分:6)

tl; dr:我怀疑您在转换仅包含<?的行时以某种方式删除了一行结尾。

您的脚本已删除修补程序中的重要行,或者您已更改标题。 catalog/product_info_v3.php差异的第一个大块格式不正确。

它的标题是:

@@ -186,7 +186,7 @@ function doRequestComplete() {

表示有关hunk如何与 preimage (原始文件)和 postimage (通过应用此补丁生成)的信息。前像信息以-为前缀,为-186,7,表示该块包含来自原像的7行,从第186行开始。后图信息以+为前缀,并且是+186,7,表示从第186行开始,此大块将向postimage发出7行。

这7行可以包含上下文(共同的行,前缀为空格),仅存在于原像中的行(前缀为-),或仅存在于postimage中的行(前缀为+)。

查看大块然后用其类型标记每一行:

  context:         }
  context:     }
  context:  <?php -if ((STORES_ID == 10) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
postimage: +if (((STORES_ID == 10) || (STORES_ID == 26)) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
  context:  function doCheckBW2016PlaqueProperty() {
  context:     thePropertyNumber = document.getElementById('propertyToCheck');
  context:     if (thePropertyNumber.value == "") {

context行再次出现在原像和后像中。因此,preimage共有6行,postimage有7行。

但是你的标题表示原始图像有7行!因此标题错误或指令错误。 (并且Git期望在第37行看到另一行的原像,但它是一个新的标题行,所以Git确定你的补丁文件已损坏。)

此补丁中的行表示您将if行添加到postimage中,而preimage中不存在该行。如果这是正确的,那么你已经破坏了标题,它应该是-186,6 +186,7,表示有一条线被添加到postimage。

或者,如果你更改 if行,那么你已经省略了它的原像状态,你应该在postimage行上方有一行。

仔细观察,看起来您在上面的<?php之后实际上错过了换行符。您的上下文可能不是<?php -if ...,因为我怀疑这是无效的PHP,if前面有一个连字符。

怀疑这个大块应该是这样的:

@@ -186,7 +186,7 @@ function doRequestComplete() {
       }
   }
 <?php
-if ((STORES_ID == 10) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
+if (((STORES_ID == 10) || (STORES_ID == 26)) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
 function doCheckBW2016PlaqueProperty() {
    thePropertyNumber = document.getElementById('propertyToCheck');
    if (thePropertyNumber.value == "") {

哪个没有腐败,现在有7行preimage(六个上下文行,加上仅存在于preimage中的前缀为-的行)和7行postimage(六行)上下文行,加上仅存在于前缀中的+前缀的行。)

所以现在我们有一个合法的补丁,因为说明符合标题。

答案 1 :(得分:1)

追求爱德华的最高级回答这个问题,我仔细研究了“之前”和“之后”的补丁文件。好吧,我还不确定我的正则表达式是如何这个,但显然,这就是所做的:

原始补丁文件:

<?
-if ((STORES_ID == 10) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
+if (((STORES_ID == 10) || (STORES_ID == 26)) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>

......和我的正则表达式之后的那个人完成了它:

 <?php -if ((STORES_ID == 10) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
+if (((STORES_ID == 10) || (STORES_ID == 26)) && (in_array($products_id, $bwFreePlaqueIDList2016))) { ?>
 function doCheckBW2016PlaqueProperty() {

有什么问题? “新线”消失了。

感觉既困惑又有点愚蠢,我看了我的(PHP)代码:

$content = preg_replace('/\<\?\s*(?=[^xp=])/', '<?php ', $content);

和-d-d-d ......,“就是这样。”的: - /

这个明显错误的(某种方式......?)正则表达式的 intent 是使用“零长度正向前瞻断言”{ {1}}查找尚未(?=<?的{​​{1}}代码。

(哇!)“D'哦!”

我正在使用肯定的预测断言来对以下字符列表中的“not 进行测试。在这种情况下,我应该使用否定预测:<?php非常确定会不会消耗换行符。(我不是一次读取一行文件。我只是啜饮整个事情。)

编辑#2: ...而且,在这么多毫秒内,正确的答案出现在评论#1中:<?xml正在消费换行符,而负面预测正在使用似乎根本没有工作)是不必要的。 (事实上,(?![px=])根本不应该存在!)再次使用正向前瞻,删除\s*,而只用\s*替换同样的事情后跟一个空格...脚本有效:

\s*

最诚挚和热情的感谢给所有帮助我解决这个问题的人。 (尤其是爱德华,他刚刚向我们所有人详细解释了这些补丁文件是如何格式化的!)

答案 2 :(得分:1)

当我尝试粘贴( Ctrl + C -> Ctrl + V )修补程序时,出现了此错误:

$ git patch
[Ctrl+Shift+V to paste in terminal]
[Ctrl+D to end input]

这会告诉我补丁在最后一行已损坏。

解决方案是在使用 Ctrl + D 结束输入之前添加 Enter 。它缺少最后的空白行。

答案 3 :(得分:0)

这就是我谈到这个问题的方式。

  1. 我确实允许对某些文件进行修改,然后我发现应该撤消对一个文件的修改。
  2. 我尝试检出文件,但是忘记了具体的文件,我使用的是git checkout .
  3. 在结帐之前,我先进行git diff来查看修改,所以我从控制台复制了diff输出并创建了补丁文件。
  4. 然后我git应用了补丁文件,我遇到了这个问题。

如何修复它。 检查补丁文件格式从dos到unix。 (通过vim,set ff=unix