[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: svn diff produces a patch which does not reapply cleanly

From: David Ellingsworth <david_at_identd.dyndns.org>
Date: Sun, 25 Jan 2009 12:02:42 -0500

On Fri, Jan 23, 2009 at 11:42 AM, David Ellingsworth
<david_at_identd.dyndns.org> wrote:
> On Wed, Jan 7, 2009 at 5:01 PM, Konstantin Kolinko
> <knst.kolinko_at_gmail.com> wrote:
>> 2009/1/7 Stefan Küng <tortoisesvn_at_gmail.com>:
>>> David Glasser wrote:
>>>> On Wed, Jan 7, 2009 at 10:07 AM, Stefan Kueng <tortoisesvn_at_gmail.com> wrote:
>>>>> David Ellingsworth wrote:
>>>>>> On Wed, Jan 7, 2009 at 11:26 AM, Stefan Küng <tortoisesvn_at_gmail.com> wrote:
>>>>>>> Daniel Shahaf wrote:
>>>>>>>> David Ellingsworth wrote on Tue, 6 Jan 2009 at 19:57 -0500:
>>>>>>>>> While using TortoiseSVN 1.5.6 build 14908, I encountered an error
>>>>>>>>> while trying to apply a patch with TortoiseMerge that was previously
>>>>>>>>> created using TortoiseSVN's "Create Patch" feature. While I was unable
>>>>>>>>> to apply the patch with TortoiseMerge, I did succeed while using the
>>>>>>>>> standard patch command, but not without any fuzz.
>>>>>>>>> The reply to the issue I posted on TortioseSVN"s user mailing list
>>>>>>>>> indicates this is an error in svn's core since the patch generated is
>>>>>>>>> equivalent to "svn diff file > patchfile". I have verified this using
>>>>>>>>> svn client 1.5.1 and 1.5.5.
>>>>>>>>> Attached are some files I created which are capable of reliably
>>>>>>>>> reproducing the problem. The files are as follows: the original
>>>>>>>>> file(test.txt), the updated file(test_v2.txt), and the associated
>>>>>>>>> patch file generated from svn diff(test.patch).
>>>>>>>> What *exactly* should we do with these three files to reproduce the error?
>>>>>>>> (If you can package the answer in script (or transcript) form, that's
>>>>>>>> best.) I tried
>>>>>>>> svn add wc1\trunk\test.txt
>>>>>>>> svn commit wc1 -m "add"
>>>>>>>> rm -f wc1\trunk\test.txt
>>>>>>>> cp wc1\trunk\test_v2.txt wc1\trunk\test.txt
>>>>>>>> svn diff wc1 > out
>>>>>>>> vim -Nu NONE -c "%s/\r//" -c "wq ++ff=dos" out
>>>>>>>> svn revert wc1\trunk\test.txt
>>>>>>>> patch -d wc1\trunk < out
>>>>>>>> diff -u wc1\trunk\test*.txt
>>>>>>>> but it didn't cause any error message, and the 'diff -u' at the end also
>>>>>>>> found no differences (the expected result). Results are the same with
>>>>>>>> both 1.5 and trunk.
>>>>>>> Try
>>>>>>> svn add wc1\trunk\test.txt
>>>>>>> svn commit wc1 -m "add"
>>>>>>> cp test_v2.txt wc1\trunk\test.txt
>>>>>>> svn diff wc1 > out
>>>>>>> svn revert wc1\trunk\test.txt
>>>>>>> patch -d wc1\trunk < out
>>>>>>> Stefan
>>>>>> Output is as follows, I don't have a trunk directory so it's been excluded:
>>>>>> $ svn add wc1\test.txt
>>>>>> A wc1\test.txt
>>>>>> $ svn commit wc1 -m "add"
>>>>>> Adding wc1\test.txt
>>>>>> Transmitting file data .
>>>>>> Committed revision 1.
>>>>>> $ cp test_v2.txt wc1\test.txt
>>>>>> $ svn diff wc1 > out
>>>>>> $ svn revert wc1\test.txt
>>>>>> Reverted 'wc1\test.txt'
>>>>>> $ patch -d wc1 < out
>>>>>> patching file 'test.txt'
>>>>>> Hunk #2 succeeded at 7 (offset 2 lines)
>>>>> sure, the patch can be applied, but not cleanly - 'offset 2 lines'.
>>>>> The patch should be applied cleanly, without any offset.
>>>>> I haven't found any clear docs on how a patch file really is defined,
>>>>> but from what I think is wrong:
>>>>> The chunk info line
>>>>> @@ -2,9 +5,9 @@
>>>>> is wrong. AFAIK the first number (-2) is the line number where removing
>>>>> starts, the second one the number of lines to remove (including context
>>>>> lines), the third one (5) the line number where adding starts and the
>>>>> fourth (9) the number of lines to add (also including context lines).
>>>>> Now, in 1.4.x, the diff would have the start line numbers adjusted. The
>>>>> first chunk is always correct, but now (>= 1.5.x) the line numbers are
>>>>> always in reference to the original file. Before those lines were
>>>>> adjusted: if a chunk before added lines or removed lines, the 'start'
>>>>> lines of the following chunks would take that into account.
>>>>> Does anyone know if (and where) the patch file format is documented?
>>>>> Because I may be completely wrong here - I've implemented the patch
>>>>> functionality in TortoiseMerge completely by reverse engineering the
>>>>> format...
>>>> I get the same patch with 1.4.x and ~trunk (with that line), FWIW.
>>>> You get something different with 1.4.x?
>>> hmm - no. I also get the same patch with 1.4.x and even 1.3.x.
>>> Problem still is: the original 'patch' tool can't apply that patch
>>> cleanly without doing 'fuzzy' work. Which means the patch is not correct?
>>> If there was a documentation on how a patch has to be created and how
>>> those chunk infos are supposed to work, it would be easier...
>>> Stefan
>> Here is the specification:
>> It is POSIX.1-2008 (The Open Group Base Specifications Issue 7)
>> http://www.opengroup.org/onlinepubs/9699919799/utilities/diff.html
>> http://www.opengroup.org/onlinepubs/9699919799/utilities/patch.html
>> Note: The entrance is here:
>> http://www.opengroup.org/bookstore/catalog/c082.htm
>> They ask for your name and assign you a cookie.
>> The previous Issue 6 is freely accessible here, though it does not yet
>> specify the -u format:
>> http://www.opengroup.org/onlinepubs/009695399/utilities/diff.html
>> Best regards,
>> Konstantin Kolinko
> I haven't heard much about this issue since I submitted it. Is a fix
> planned for this or is there a work around I can use in the mean time?

Building a bit on the previous issue, I've updated the test files to
show the full extent of the problem. Attached are the updated files.
test.txt is the original file committed to the archive, test_v2.txt is
the modified version of test.txt, and test.patch is the resulting
output from svn diff. If test.txt is reverted to the original version
and the patch applied with patch -p0 < test.patch, patch produces the
following output:

$ patch -p0 < test.patch
patching file 'test.txt'
Hunk #2 succeeded at 7 (offset 2 lines).
Hunk #3 succeeded at 11 (offset -2 lines).
Hunk #4 succeeded at 25 (offset 2 lines).
Hunk #5 succeeded at 31 (offset -2 lines).

As you can see, the patch does not apply cleanly. The correct offset
should be 0 lines for a perfect patch file. As you can see.. not only
is the offset of the second hunk wrong, but all following hunks are
wrong as well.


David Ellingsworth


Received on 2009-01-25 18:42:32 CET

This is an archived mail posted to the Subversion Dev mailing list.