Subject: bin/2215: patch breaks on diffs against '.'
To: None <gnats-bugs@NetBSD.ORG>
From: Christian Bauernfeind <chrisbfd@theorie3.physik.uni-erlangen.de>
List: netbsd-bugs
Date: 03/14/1996 10:43:33
>Number:         2215
>Category:       bin
>Synopsis:       /usr/bin/patch is completely, utterly broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 14 05:05:00 1996
>Last-Modified:
>Originator:     Christian Bauernfeind &
>Organization:
>Release:        1.1
>Environment:
Amiga 3000T
System: NetBSD fortress 1.1A NetBSD 1.1A (FORTRESS) #2: Sat Mar 9 14:29:11 MET 1996 root@fortress:/local/sys/arch/amiga/compile/FORTRESS amiga


>Description:

Under certain circumstances, patch tries to patch a file in the
current directory if it has the same name as on higher up in the
directory hierarchy that it should patch.
It creates new files in the current directory instead of their proper
directory.
When it should empty a file, it asks for a file to patch instead of
using the existing one.
(The latter two apply to diffs created with -P/-N.)
Sometimes it mixes up source and destination and wrongly assumes 
a reversed patch.
The -f optios does not ignore missing files, as advertised in the man
page, but breaks off the patching.


>How-To-Repeat:

For the first three:
Unpack the included sh-archive, then 
cd test2
diff -crNP ../test1 . > diff
patch < diff

For the fourth one:
Unpack the sh-archive
diff -crNP test1 test2 > diff
(or diff -crNP test2 test1 > diff)
patch < diff

The one that works:
diff -crNP test1 test2 > diff
cd test2
patch -p1 < ../diff

The -f option:
diff -crNP test1 test2 > diff
cd test2
rm bar/baz
patch -p1 < ../diff

>Fix:

Do not prepare diffs against '.'. This appears to circumvent the first
three problems.
I'm not sure whether the fourth is a bug or a feature.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	.
#	./test1
#	./test1/foo
#	./test1/foo/wibble
#	./test1/bar
#	./test1/bar/baz
#	./test1/baz
#	./test2
#	./test2/bar
#	./test2/bar/baz
#	./test2/baz
#	./test2/garble
#	./test2/garble/wibble
#
echo c - .
mkdir -p . > /dev/null 2>&1
echo c - ./test1
mkdir -p ./test1 > /dev/null 2>&1
echo c - ./test1/foo
mkdir -p ./test1/foo > /dev/null 2>&1
echo x - ./test1/foo/wibble
sed 's/^X//' >./test1/foo/wibble << 'END-of-./test1/foo/wibble'
Xwobble
END-of-./test1/foo/wibble
echo c - ./test1/bar
mkdir -p ./test1/bar > /dev/null 2>&1
echo x - ./test1/bar/baz
sed 's/^X//' >./test1/bar/baz << 'END-of-./test1/bar/baz'
Xlollipop
END-of-./test1/bar/baz
echo x - ./test1/baz
sed 's/^X//' >./test1/baz << 'END-of-./test1/baz'
Xblargl
END-of-./test1/baz
echo c - ./test2
mkdir -p ./test2 > /dev/null 2>&1
echo c - ./test2/bar
mkdir -p ./test2/bar > /dev/null 2>&1
echo x - ./test2/bar/baz
sed 's/^X//' >./test2/bar/baz << 'END-of-./test2/bar/baz'
Xjabberwocky
END-of-./test2/bar/baz
echo x - ./test2/baz
sed 's/^X//' >./test2/baz << 'END-of-./test2/baz'
Xblargl
END-of-./test2/baz
echo c - ./test2/garble
mkdir -p ./test2/garble > /dev/null 2>&1
echo x - ./test2/garble/wibble
sed 's/^X//' >./test2/garble/wibble << 'END-of-./test2/garble/wibble'
Xwobble
END-of-./test2/garble/wibble
exit

--
Christian Bauernfeind <chrisbfd@theorie3.physik.uni-erlangen.de>

You make a grown man cry...
>Audit-Trail:
>Unformatted: