Does `patch` work with asymmetric context?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite












I have file a:



This
file
does
have
an error
in it
that
needs
to be
fixed.


and a similar file b:



This
file
does
have
no error
in it
that
needs
to be
fixed.


I can create a unified diff with diff -u a b:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -2,7 +2,7 @@
file
does
have
-an error
+no error
in it
that
needs


And I can also reduce the context to one line on either side with diff -u1 a b:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -4,3 +4,3 @@
have
-an error
+no error
in it


Both of these patches can be applied cleanly with patch. I did not however find a way to make diff produce a patch with asymmetric context. I am assuming it cannot do that. So I tried removing some context manually, to make a patch with two lines of context before the change and one after:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -3,4 +3,4 @@
does
have
-an error
+no error
in it


This seems valid to me in the unified format. However, patch complains that it had to resort to fuzzing:



patching file a
Hunk #1 succeeded at 3 with fuzz 1.


Am I doing something wrong or is (GNU) patch actually broken for asymmetric contexts because no-one imagined they would ever be used, since diff cannot make them anyway?



Also interesting is that the patch works if I reverse the asymmetry, that is one line before and two after:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -4,4 +4,4 @@
have
-an error
+no error
in it
that






share|improve this question






















  • The asymmetry may come from the fact that the patch command counts the number of context lines (and I suspect use the context before to count that, I am not able to prove that at 100% from the source code), so in your first case it sees 2 lines of context, but then only one after, whereas in the second example it computes one line of context, and indeed it has one line of context after (and an extra line, that is ignored because patch tries to ignore "garbage" before or after the content being patched)
    – Patrick Mevzek
    Jan 4 at 23:14







  • 1




    Note that your asymmetry case is specifically part of the tests: git.savannah.gnu.org/cgit/patch.git/tree/tests/asymmetric-hunks So at least the result are per design/as expected
    – Patrick Mevzek
    Jan 4 at 23:24










  • The last line in the last patch is not ignored. patch actually checks it too and needs fuzzing if it does not match.
    – Karel Vlk
    Jan 5 at 11:51














up vote
2
down vote

favorite












I have file a:



This
file
does
have
an error
in it
that
needs
to be
fixed.


and a similar file b:



This
file
does
have
no error
in it
that
needs
to be
fixed.


I can create a unified diff with diff -u a b:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -2,7 +2,7 @@
file
does
have
-an error
+no error
in it
that
needs


And I can also reduce the context to one line on either side with diff -u1 a b:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -4,3 +4,3 @@
have
-an error
+no error
in it


Both of these patches can be applied cleanly with patch. I did not however find a way to make diff produce a patch with asymmetric context. I am assuming it cannot do that. So I tried removing some context manually, to make a patch with two lines of context before the change and one after:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -3,4 +3,4 @@
does
have
-an error
+no error
in it


This seems valid to me in the unified format. However, patch complains that it had to resort to fuzzing:



patching file a
Hunk #1 succeeded at 3 with fuzz 1.


Am I doing something wrong or is (GNU) patch actually broken for asymmetric contexts because no-one imagined they would ever be used, since diff cannot make them anyway?



Also interesting is that the patch works if I reverse the asymmetry, that is one line before and two after:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -4,4 +4,4 @@
have
-an error
+no error
in it
that






share|improve this question






















  • The asymmetry may come from the fact that the patch command counts the number of context lines (and I suspect use the context before to count that, I am not able to prove that at 100% from the source code), so in your first case it sees 2 lines of context, but then only one after, whereas in the second example it computes one line of context, and indeed it has one line of context after (and an extra line, that is ignored because patch tries to ignore "garbage" before or after the content being patched)
    – Patrick Mevzek
    Jan 4 at 23:14







  • 1




    Note that your asymmetry case is specifically part of the tests: git.savannah.gnu.org/cgit/patch.git/tree/tests/asymmetric-hunks So at least the result are per design/as expected
    – Patrick Mevzek
    Jan 4 at 23:24










  • The last line in the last patch is not ignored. patch actually checks it too and needs fuzzing if it does not match.
    – Karel Vlk
    Jan 5 at 11:51












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I have file a:



This
file
does
have
an error
in it
that
needs
to be
fixed.


and a similar file b:



This
file
does
have
no error
in it
that
needs
to be
fixed.


I can create a unified diff with diff -u a b:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -2,7 +2,7 @@
file
does
have
-an error
+no error
in it
that
needs


And I can also reduce the context to one line on either side with diff -u1 a b:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -4,3 +4,3 @@
have
-an error
+no error
in it


Both of these patches can be applied cleanly with patch. I did not however find a way to make diff produce a patch with asymmetric context. I am assuming it cannot do that. So I tried removing some context manually, to make a patch with two lines of context before the change and one after:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -3,4 +3,4 @@
does
have
-an error
+no error
in it


This seems valid to me in the unified format. However, patch complains that it had to resort to fuzzing:



patching file a
Hunk #1 succeeded at 3 with fuzz 1.


Am I doing something wrong or is (GNU) patch actually broken for asymmetric contexts because no-one imagined they would ever be used, since diff cannot make them anyway?



Also interesting is that the patch works if I reverse the asymmetry, that is one line before and two after:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -4,4 +4,4 @@
have
-an error
+no error
in it
that






share|improve this question














I have file a:



This
file
does
have
an error
in it
that
needs
to be
fixed.


and a similar file b:



This
file
does
have
no error
in it
that
needs
to be
fixed.


I can create a unified diff with diff -u a b:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -2,7 +2,7 @@
file
does
have
-an error
+no error
in it
that
needs


And I can also reduce the context to one line on either side with diff -u1 a b:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -4,3 +4,3 @@
have
-an error
+no error
in it


Both of these patches can be applied cleanly with patch. I did not however find a way to make diff produce a patch with asymmetric context. I am assuming it cannot do that. So I tried removing some context manually, to make a patch with two lines of context before the change and one after:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -3,4 +3,4 @@
does
have
-an error
+no error
in it


This seems valid to me in the unified format. However, patch complains that it had to resort to fuzzing:



patching file a
Hunk #1 succeeded at 3 with fuzz 1.


Am I doing something wrong or is (GNU) patch actually broken for asymmetric contexts because no-one imagined they would ever be used, since diff cannot make them anyway?



Also interesting is that the patch works if I reverse the asymmetry, that is one line before and two after:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -4,4 +4,4 @@
have
-an error
+no error
in it
that








share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 14:12

























asked Jan 3 at 14:06









Karel Vlk

686




686











  • The asymmetry may come from the fact that the patch command counts the number of context lines (and I suspect use the context before to count that, I am not able to prove that at 100% from the source code), so in your first case it sees 2 lines of context, but then only one after, whereas in the second example it computes one line of context, and indeed it has one line of context after (and an extra line, that is ignored because patch tries to ignore "garbage" before or after the content being patched)
    – Patrick Mevzek
    Jan 4 at 23:14







  • 1




    Note that your asymmetry case is specifically part of the tests: git.savannah.gnu.org/cgit/patch.git/tree/tests/asymmetric-hunks So at least the result are per design/as expected
    – Patrick Mevzek
    Jan 4 at 23:24










  • The last line in the last patch is not ignored. patch actually checks it too and needs fuzzing if it does not match.
    – Karel Vlk
    Jan 5 at 11:51
















  • The asymmetry may come from the fact that the patch command counts the number of context lines (and I suspect use the context before to count that, I am not able to prove that at 100% from the source code), so in your first case it sees 2 lines of context, but then only one after, whereas in the second example it computes one line of context, and indeed it has one line of context after (and an extra line, that is ignored because patch tries to ignore "garbage" before or after the content being patched)
    – Patrick Mevzek
    Jan 4 at 23:14







  • 1




    Note that your asymmetry case is specifically part of the tests: git.savannah.gnu.org/cgit/patch.git/tree/tests/asymmetric-hunks So at least the result are per design/as expected
    – Patrick Mevzek
    Jan 4 at 23:24










  • The last line in the last patch is not ignored. patch actually checks it too and needs fuzzing if it does not match.
    – Karel Vlk
    Jan 5 at 11:51















The asymmetry may come from the fact that the patch command counts the number of context lines (and I suspect use the context before to count that, I am not able to prove that at 100% from the source code), so in your first case it sees 2 lines of context, but then only one after, whereas in the second example it computes one line of context, and indeed it has one line of context after (and an extra line, that is ignored because patch tries to ignore "garbage" before or after the content being patched)
– Patrick Mevzek
Jan 4 at 23:14





The asymmetry may come from the fact that the patch command counts the number of context lines (and I suspect use the context before to count that, I am not able to prove that at 100% from the source code), so in your first case it sees 2 lines of context, but then only one after, whereas in the second example it computes one line of context, and indeed it has one line of context after (and an extra line, that is ignored because patch tries to ignore "garbage" before or after the content being patched)
– Patrick Mevzek
Jan 4 at 23:14





1




1




Note that your asymmetry case is specifically part of the tests: git.savannah.gnu.org/cgit/patch.git/tree/tests/asymmetric-hunks So at least the result are per design/as expected
– Patrick Mevzek
Jan 4 at 23:24




Note that your asymmetry case is specifically part of the tests: git.savannah.gnu.org/cgit/patch.git/tree/tests/asymmetric-hunks So at least the result are per design/as expected
– Patrick Mevzek
Jan 4 at 23:24












The last line in the last patch is not ignored. patch actually checks it too and needs fuzzing if it does not match.
– Karel Vlk
Jan 5 at 11:51




The last line in the last patch is not ignored. patch actually checks it too and needs fuzzing if it does not match.
– Karel Vlk
Jan 5 at 11:51










2 Answers
2






active

oldest

votes

















up vote
0
down vote













The POSIX standard doesn't provide a way to generate asymmetric contexts. GNU patch is being helpful in one case by accepting a malformed patch.



By the way, the manual page indicated in the question makes an incorrect statement:




At present, only GNU diff can produce this format and only GNU patch can automatically apply diffs in this format. For proper operation, patch typically needs at least three lines of context.




The error is still in the diffutils info file.



POSIX patch handles unified diffs.






share|improve this answer






















  • Would the patches above be considered malformed?
    – Karel Vlk
    Jan 4 at 11:23










  • sure: the unified diff format is only defined in terms of diff and patch. Since diff won't produce asymmetric diffs (and is the only standardized producer of unified diffs), they're outside the definition.
    – Thomas Dickey
    Jan 4 at 20:43


















up vote
0
down vote













GNU patch just does not like when there is more prefix context than suffix context. A simple but ugly workaround is to convert the first line of context into a no-op change like this:



--- a 2018-01-03 14:20:22 +0100
+++ b 2018-01-03 14:20:37 +0100
@@ -3,4 +3,4 @@
-does
+does
have
-an error
+no error
in it


This removes all prefix context. It's OK when there is more suffix context.



I did go through patch's source code and found the offending piece. Without understanding it too deeply, I came up with a simple fix similar to how prefix context is already handled in the code. Here is my output of git diff (a patch for patch):



diff --git a/src/patch.c b/src/patch.c
index bba7e0e..e661af1 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -1171,7 +1171,7 @@ locate_hunk (lin fuzz)
else if (prefix_fuzz < 0)
prefix_fuzz = 0;

- if (suffix_fuzz < 0)
+ if (suffix_fuzz < 0 && pch_first () + pat_lines > input_lines)

/* Can only match end of file. */
offset = first_guess - (input_lines - pat_lines + 1);
@@ -1184,6 +1184,8 @@ locate_hunk (lin fuzz)
else
return 0;

+ else if (suffix_fuzz < 0)
+ suffix_fuzz = 0;

min_offset = max_pos_offset < 0 ? first_guess - max_where
: max_neg_offset < 0 ? first_guess - min_where
diff --git a/tests/asymmetric-hunks b/tests/asymmetric-hunks
index d6979d9..86e4ef9 100644
--- a/tests/asymmetric-hunks
+++ b/tests/asymmetric-hunks
@@ -77,5 +77,4 @@ seq 1 5 > a

check 'patch < a.diff' <<EOF
patching file a
-Hunk #1 succeeded at 2 with fuzz 1.
EOF


As @Patrick Mevzek pointed out, there already is a regression test for asymmetric contexts. So that is also corrected to not expect fuzzing. Unfortunately the merge test also fails in one case and I am not sure why. I guess I cannot submit the patch because of this. It would be nice if someone with more insight could come up with a better fix.






share|improve this answer




















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f414542%2fdoes-patch-work-with-asymmetric-context%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    The POSIX standard doesn't provide a way to generate asymmetric contexts. GNU patch is being helpful in one case by accepting a malformed patch.



    By the way, the manual page indicated in the question makes an incorrect statement:




    At present, only GNU diff can produce this format and only GNU patch can automatically apply diffs in this format. For proper operation, patch typically needs at least three lines of context.




    The error is still in the diffutils info file.



    POSIX patch handles unified diffs.






    share|improve this answer






















    • Would the patches above be considered malformed?
      – Karel Vlk
      Jan 4 at 11:23










    • sure: the unified diff format is only defined in terms of diff and patch. Since diff won't produce asymmetric diffs (and is the only standardized producer of unified diffs), they're outside the definition.
      – Thomas Dickey
      Jan 4 at 20:43















    up vote
    0
    down vote













    The POSIX standard doesn't provide a way to generate asymmetric contexts. GNU patch is being helpful in one case by accepting a malformed patch.



    By the way, the manual page indicated in the question makes an incorrect statement:




    At present, only GNU diff can produce this format and only GNU patch can automatically apply diffs in this format. For proper operation, patch typically needs at least three lines of context.




    The error is still in the diffutils info file.



    POSIX patch handles unified diffs.






    share|improve this answer






















    • Would the patches above be considered malformed?
      – Karel Vlk
      Jan 4 at 11:23










    • sure: the unified diff format is only defined in terms of diff and patch. Since diff won't produce asymmetric diffs (and is the only standardized producer of unified diffs), they're outside the definition.
      – Thomas Dickey
      Jan 4 at 20:43













    up vote
    0
    down vote










    up vote
    0
    down vote









    The POSIX standard doesn't provide a way to generate asymmetric contexts. GNU patch is being helpful in one case by accepting a malformed patch.



    By the way, the manual page indicated in the question makes an incorrect statement:




    At present, only GNU diff can produce this format and only GNU patch can automatically apply diffs in this format. For proper operation, patch typically needs at least three lines of context.




    The error is still in the diffutils info file.



    POSIX patch handles unified diffs.






    share|improve this answer














    The POSIX standard doesn't provide a way to generate asymmetric contexts. GNU patch is being helpful in one case by accepting a malformed patch.



    By the way, the manual page indicated in the question makes an incorrect statement:




    At present, only GNU diff can produce this format and only GNU patch can automatically apply diffs in this format. For proper operation, patch typically needs at least three lines of context.




    The error is still in the diffutils info file.



    POSIX patch handles unified diffs.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 3 at 21:30

























    answered Jan 3 at 21:13









    Thomas Dickey

    49.5k584155




    49.5k584155











    • Would the patches above be considered malformed?
      – Karel Vlk
      Jan 4 at 11:23










    • sure: the unified diff format is only defined in terms of diff and patch. Since diff won't produce asymmetric diffs (and is the only standardized producer of unified diffs), they're outside the definition.
      – Thomas Dickey
      Jan 4 at 20:43

















    • Would the patches above be considered malformed?
      – Karel Vlk
      Jan 4 at 11:23










    • sure: the unified diff format is only defined in terms of diff and patch. Since diff won't produce asymmetric diffs (and is the only standardized producer of unified diffs), they're outside the definition.
      – Thomas Dickey
      Jan 4 at 20:43
















    Would the patches above be considered malformed?
    – Karel Vlk
    Jan 4 at 11:23




    Would the patches above be considered malformed?
    – Karel Vlk
    Jan 4 at 11:23












    sure: the unified diff format is only defined in terms of diff and patch. Since diff won't produce asymmetric diffs (and is the only standardized producer of unified diffs), they're outside the definition.
    – Thomas Dickey
    Jan 4 at 20:43





    sure: the unified diff format is only defined in terms of diff and patch. Since diff won't produce asymmetric diffs (and is the only standardized producer of unified diffs), they're outside the definition.
    – Thomas Dickey
    Jan 4 at 20:43













    up vote
    0
    down vote













    GNU patch just does not like when there is more prefix context than suffix context. A simple but ugly workaround is to convert the first line of context into a no-op change like this:



    --- a 2018-01-03 14:20:22 +0100
    +++ b 2018-01-03 14:20:37 +0100
    @@ -3,4 +3,4 @@
    -does
    +does
    have
    -an error
    +no error
    in it


    This removes all prefix context. It's OK when there is more suffix context.



    I did go through patch's source code and found the offending piece. Without understanding it too deeply, I came up with a simple fix similar to how prefix context is already handled in the code. Here is my output of git diff (a patch for patch):



    diff --git a/src/patch.c b/src/patch.c
    index bba7e0e..e661af1 100644
    --- a/src/patch.c
    +++ b/src/patch.c
    @@ -1171,7 +1171,7 @@ locate_hunk (lin fuzz)
    else if (prefix_fuzz < 0)
    prefix_fuzz = 0;

    - if (suffix_fuzz < 0)
    + if (suffix_fuzz < 0 && pch_first () + pat_lines > input_lines)

    /* Can only match end of file. */
    offset = first_guess - (input_lines - pat_lines + 1);
    @@ -1184,6 +1184,8 @@ locate_hunk (lin fuzz)
    else
    return 0;

    + else if (suffix_fuzz < 0)
    + suffix_fuzz = 0;

    min_offset = max_pos_offset < 0 ? first_guess - max_where
    : max_neg_offset < 0 ? first_guess - min_where
    diff --git a/tests/asymmetric-hunks b/tests/asymmetric-hunks
    index d6979d9..86e4ef9 100644
    --- a/tests/asymmetric-hunks
    +++ b/tests/asymmetric-hunks
    @@ -77,5 +77,4 @@ seq 1 5 > a

    check 'patch < a.diff' <<EOF
    patching file a
    -Hunk #1 succeeded at 2 with fuzz 1.
    EOF


    As @Patrick Mevzek pointed out, there already is a regression test for asymmetric contexts. So that is also corrected to not expect fuzzing. Unfortunately the merge test also fails in one case and I am not sure why. I guess I cannot submit the patch because of this. It would be nice if someone with more insight could come up with a better fix.






    share|improve this answer
























      up vote
      0
      down vote













      GNU patch just does not like when there is more prefix context than suffix context. A simple but ugly workaround is to convert the first line of context into a no-op change like this:



      --- a 2018-01-03 14:20:22 +0100
      +++ b 2018-01-03 14:20:37 +0100
      @@ -3,4 +3,4 @@
      -does
      +does
      have
      -an error
      +no error
      in it


      This removes all prefix context. It's OK when there is more suffix context.



      I did go through patch's source code and found the offending piece. Without understanding it too deeply, I came up with a simple fix similar to how prefix context is already handled in the code. Here is my output of git diff (a patch for patch):



      diff --git a/src/patch.c b/src/patch.c
      index bba7e0e..e661af1 100644
      --- a/src/patch.c
      +++ b/src/patch.c
      @@ -1171,7 +1171,7 @@ locate_hunk (lin fuzz)
      else if (prefix_fuzz < 0)
      prefix_fuzz = 0;

      - if (suffix_fuzz < 0)
      + if (suffix_fuzz < 0 && pch_first () + pat_lines > input_lines)

      /* Can only match end of file. */
      offset = first_guess - (input_lines - pat_lines + 1);
      @@ -1184,6 +1184,8 @@ locate_hunk (lin fuzz)
      else
      return 0;

      + else if (suffix_fuzz < 0)
      + suffix_fuzz = 0;

      min_offset = max_pos_offset < 0 ? first_guess - max_where
      : max_neg_offset < 0 ? first_guess - min_where
      diff --git a/tests/asymmetric-hunks b/tests/asymmetric-hunks
      index d6979d9..86e4ef9 100644
      --- a/tests/asymmetric-hunks
      +++ b/tests/asymmetric-hunks
      @@ -77,5 +77,4 @@ seq 1 5 > a

      check 'patch < a.diff' <<EOF
      patching file a
      -Hunk #1 succeeded at 2 with fuzz 1.
      EOF


      As @Patrick Mevzek pointed out, there already is a regression test for asymmetric contexts. So that is also corrected to not expect fuzzing. Unfortunately the merge test also fails in one case and I am not sure why. I guess I cannot submit the patch because of this. It would be nice if someone with more insight could come up with a better fix.






      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        GNU patch just does not like when there is more prefix context than suffix context. A simple but ugly workaround is to convert the first line of context into a no-op change like this:



        --- a 2018-01-03 14:20:22 +0100
        +++ b 2018-01-03 14:20:37 +0100
        @@ -3,4 +3,4 @@
        -does
        +does
        have
        -an error
        +no error
        in it


        This removes all prefix context. It's OK when there is more suffix context.



        I did go through patch's source code and found the offending piece. Without understanding it too deeply, I came up with a simple fix similar to how prefix context is already handled in the code. Here is my output of git diff (a patch for patch):



        diff --git a/src/patch.c b/src/patch.c
        index bba7e0e..e661af1 100644
        --- a/src/patch.c
        +++ b/src/patch.c
        @@ -1171,7 +1171,7 @@ locate_hunk (lin fuzz)
        else if (prefix_fuzz < 0)
        prefix_fuzz = 0;

        - if (suffix_fuzz < 0)
        + if (suffix_fuzz < 0 && pch_first () + pat_lines > input_lines)

        /* Can only match end of file. */
        offset = first_guess - (input_lines - pat_lines + 1);
        @@ -1184,6 +1184,8 @@ locate_hunk (lin fuzz)
        else
        return 0;

        + else if (suffix_fuzz < 0)
        + suffix_fuzz = 0;

        min_offset = max_pos_offset < 0 ? first_guess - max_where
        : max_neg_offset < 0 ? first_guess - min_where
        diff --git a/tests/asymmetric-hunks b/tests/asymmetric-hunks
        index d6979d9..86e4ef9 100644
        --- a/tests/asymmetric-hunks
        +++ b/tests/asymmetric-hunks
        @@ -77,5 +77,4 @@ seq 1 5 > a

        check 'patch < a.diff' <<EOF
        patching file a
        -Hunk #1 succeeded at 2 with fuzz 1.
        EOF


        As @Patrick Mevzek pointed out, there already is a regression test for asymmetric contexts. So that is also corrected to not expect fuzzing. Unfortunately the merge test also fails in one case and I am not sure why. I guess I cannot submit the patch because of this. It would be nice if someone with more insight could come up with a better fix.






        share|improve this answer












        GNU patch just does not like when there is more prefix context than suffix context. A simple but ugly workaround is to convert the first line of context into a no-op change like this:



        --- a 2018-01-03 14:20:22 +0100
        +++ b 2018-01-03 14:20:37 +0100
        @@ -3,4 +3,4 @@
        -does
        +does
        have
        -an error
        +no error
        in it


        This removes all prefix context. It's OK when there is more suffix context.



        I did go through patch's source code and found the offending piece. Without understanding it too deeply, I came up with a simple fix similar to how prefix context is already handled in the code. Here is my output of git diff (a patch for patch):



        diff --git a/src/patch.c b/src/patch.c
        index bba7e0e..e661af1 100644
        --- a/src/patch.c
        +++ b/src/patch.c
        @@ -1171,7 +1171,7 @@ locate_hunk (lin fuzz)
        else if (prefix_fuzz < 0)
        prefix_fuzz = 0;

        - if (suffix_fuzz < 0)
        + if (suffix_fuzz < 0 && pch_first () + pat_lines > input_lines)

        /* Can only match end of file. */
        offset = first_guess - (input_lines - pat_lines + 1);
        @@ -1184,6 +1184,8 @@ locate_hunk (lin fuzz)
        else
        return 0;

        + else if (suffix_fuzz < 0)
        + suffix_fuzz = 0;

        min_offset = max_pos_offset < 0 ? first_guess - max_where
        : max_neg_offset < 0 ? first_guess - min_where
        diff --git a/tests/asymmetric-hunks b/tests/asymmetric-hunks
        index d6979d9..86e4ef9 100644
        --- a/tests/asymmetric-hunks
        +++ b/tests/asymmetric-hunks
        @@ -77,5 +77,4 @@ seq 1 5 > a

        check 'patch < a.diff' <<EOF
        patching file a
        -Hunk #1 succeeded at 2 with fuzz 1.
        EOF


        As @Patrick Mevzek pointed out, there already is a regression test for asymmetric contexts. So that is also corrected to not expect fuzzing. Unfortunately the merge test also fails in one case and I am not sure why. I guess I cannot submit the patch because of this. It would be nice if someone with more insight could come up with a better fix.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 5 at 18:51









        Karel Vlk

        686




        686






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f414542%2fdoes-patch-work-with-asymmetric-context%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?