Benno,

2017-09-02 18:11 GMT+02:00 Benno Schulenberg <bensb...@telfort.nl>:
>
> Hi,
>
> When two hunks in a patch have the exact same context, and in the
> file that the patch applies to one of the two contexts has changed
> a bit (in such a way that hunk #1 would apply fine with fuzz 1),
> then *both* hunks mistakenly get applied to the place where the
> context hasn't changed.
>
> For an example, see the attached file and patch.  Apply the patch
> with 'patch -p1 <goes-wrong.patch' and see the output:
>
> patching file testor.c
> Hunk #1 succeeded at 44 (offset 37 lines).
>
> It does not say anything about hunk #2 -- which is wrong, because
> after applying hunk #1 in the wrong place, the context for hunk #2
> has changed, and it can only apply the second hunk with fuzz 2.
>
>
> Expected behavior: at the very least, 'patch' should mention that
> hunk #2 was applied with fuzz 2.  And maybe patching should fail
> entirely, because when both hunks get applied to the same spot,
> also hunk #1 has in the end result factually been applied with
> fuzz 2.
>
> The ideal behavior would be that 'patch' tries to minimize the
> overall amount of fuzz.  When it notices that applying hunk #1
> with an offset of 37 lines results in a total fuzz of 2 (or 4),
> it should try to apply hunk #1 with fuzz 1.  When it does that,
> it will see that hunk #2 applies cleanly, so the total amount
> of fuzz will be just 1, which is better than 2.  So the fuzz 1
> alternative should be chosen.
>
> (I could also imagine that patch would make use of the function
> name mentioned in the @@ line: applying a hunk outside of that
> function would count as fuzz 1.5, so that it becomes better to
> accept a little fuzz within a function than to accept a perfect
> match outside of that function.)

I'm getting the following result with current patch, which differs
from what you are getting:

$ patch -i goes-wrong.patch -o testor.c.out testor.c
patching file testor.c.out (read from testor.c)
Hunk #1 succeeded at 7 with fuzz 1.
Hunk #2 succeeded at 56 with fuzz 2 (offset 8 lines).

The algorithm patch uses for matching hunks is rather crude: it tries
to match a hunk anywhere in the file with fuzz 0, then with fuzz 1,
etc. When a hunk matches, it is applied and the remaining hunks are
matched against the rest of the file (that is, the second hunk will
not be applied before the first one). There is no global optimization
of fuzz or anything like that. When a patch applies with fuzz, it is
best to check the result rather than relying on patch to do the right
thing.

Apart from fixing bugs, we cannot easily change this behavior: people
have come to expect patch to behave the way it does.

Andreas

Reply via email to