[PATCH] patch patch

Denys Vlasenko vda.linux at googlemail.com
Mon Aug 22 02:56:32 UTC 2011


On Saturday 20 August 2011 07:18, Rob Landley wrote:
> On 08/16/2011 03:57 PM, Denys Vlasenko wrote:
> > On Monday 15 August 2011 03:41, Rob Landley wrote:
> >> Commit 8027a202a89b31b, from me, was broken.  I'm an idiot sometimes.
> >>
> >> Patch needs to be able to create new files.  It's got some header magic
> >> to indicate a file didn't used ot exist (either a name /dev/null or a
> >> file date around "The epoch" I.E. unix time zero).
> >>
> >> But _within_ the new file, it's got one big hunk with no leading or
> >> trailing context lines.  The logic of this boils down to modifying an
> >> empty file where it needs to match the start of the file _and_ the end
> >> of the file.  The test for matching the end of the file is "less
> >> trailing context lines than leading context lines".  (Same amount before
> >> and after is a normal interstitial hunk.)
> >>
> >> Except zero leading context lines means you can't have LESS than that at
> >> the end, meaning zero is a special case.
> >>
> >> Add zero as a special case, restoring patch's ability to create files.
> >>
> >> We didn't have a test case for this?  Nobody noticed since November of
> >> last year?
> > 
> > Apparently so. I constructed one now:
> > 
> > testing "patch creates new file" \
> >         'patch 2>&1; echo $?; cat testfile; rm testfile' \
> > "\
> > creating testfile
> > 0
> > qwerty
> > " "" "\
> > --- /dev/null
> > +++ testfile
> > @@ -0,0 +1 @@
> > +qwerty
> > "
> > 
> > With your patch, it passes.
> > 
> > However. With your patch, another test in testsuite breaks.
> > 
> > Before patch:
> > 
> > $ cd testsuite
> > $ ./runtest patch
> > PASS: patch with old_file == new_file
> > PASS: patch with nonexistent old_file
> > PASS: patch -R with nonexistent old_file
> > PASS: patch detects already applied hunk
> > PASS: patch detects already applied hunk at the EOF
> > PASS: patch -N ignores already applied hunk
> > PASS: patch FILE PATCH
> > PASS: patch at the beginning
> > FAIL: patch creates new file
> > 1 failure(s) detected; running with -v (verbose) will give more info
> > 
> > After patch:
> > 
> > $ ./runtest patch
> > PASS: patch with old_file == new_file
> > PASS: patch with nonexistent old_file
> > PASS: patch -R with nonexistent old_file
> > PASS: patch detects already applied hunk
> > PASS: patch detects already applied hunk at the EOF
> > PASS: patch -N ignores already applied hunk
> > PASS: patch FILE PATCH
> > FAIL: patch at the beginning
> > PASS: patch creates new file
> > 1 failure(s) detected; running with -v (verbose) will give more info
> > 
> > So, unfortunately, patch needs more patching...
> > 
> > (I commited the "patch creates new file" testcase to git)
> > 
> 
> I ran "make test" and it kept saying bad substitution because so many of
> the tests say #!/bin/sh at the top and thus pick up the Defective
> Annoying SHell on Ubuntu.
> 
> Is there a reason you don't say #!/bin/bash?

Because I test it on machines with /bin/sh -> bash or /bin/sh -> ash,
not against dash. dash users need to send patches.


> So, tweak that file, cd down into the directory, run ./patch.tests
> and... Half the tests fail?

README file is there for a reason:
===================================
To run the test suite, change to this directory and run "./runtest".  It will
run all of the test cases, and list those with unexpected outcomes.  Adding the
-v option will cause it to show expected outcomes as well.  To only run the test
cases for particular applets:

./runtest <applet1> <applet2>...
===================================

Here what I'm getting:

# ./patch.tests
PASS: patch with old_file == new_file
PASS: patch with nonexistent old_file
PASS: patch -R with nonexistent old_file
FAIL: patch detects already applied hunk
FAIL: patch detects already applied hunk at the EOF
FAIL: patch -N ignores already applied hunk
PASS: patch FILE PATCH
PASS: patch at the beginning
FAIL: patch creates new file

# ./runtest patch
PASS: patch with old_file == new_file
PASS: patch with nonexistent old_file
PASS: patch -R with nonexistent old_file
PASS: patch detects already applied hunk
PASS: patch detects already applied hunk at the EOF
PASS: patch -N ignores already applied hunk
PASS: patch FILE PATCH
FAIL: patch at the beginning
PASS: patch creates new file
1 failure(s) detected; running with -v (verbose) will give more info

> Because your tests fail when run against gnu patch.  (The reversed
> patch message isn't identical, and the prompt 
> vs complain behavior differs.  Fun.  I'm not sure that's a valid test
> suite?)

We are not trying to mimic output that closely, I guess.


> Anyway, the proper fix is attached.  I tested the wrong variable, need
> to check if the _trailing_ context is zero, not the leading context.

Applied.

# ./runtest patch
PASS: patch with old_file == new_file
PASS: patch with nonexistent old_file
PASS: patch -R with nonexistent old_file
PASS: patch detects already applied hunk
PASS: patch detects already applied hunk at the EOF
PASS: patch -N ignores already applied hunk
PASS: patch FILE PATCH
PASS: patch at the beginning
PASS: patch creates new file

Thanks!

-- 
vda


More information about the busybox mailing list