Applying a patch that adds an empty file
Greg Ward
greg at gerg.ca
Thu Jul 1 12:32:16 CDT 2010
I've been investigating transplant problems and stumbled across
http://mercurial.selenic.com/bts/issue2135. The core of the bug there
seems to be that patch never fails when applying a patch that adds an
empty file. As a result, it's possible for patch.patch() to claim
success even though it did not make any changes. That makes
transplant crash -- see the simplified test script in that bug report
(http://mercurial.selenic.com/bts/msg12965) if you want an example.
But this seems like a bug in patch.py to me. First, here's patch
behaving as it should:
$ cat patch1
diff --git a/a b/a
new file mode 100644
--- /dev/null
+++ b/a
@@ -0,0 +1,1 @@
+foo
$ hg patch --no-commit -f patch1
applying patch1
$ hg patch --no-commit -f patch1
applying patch1
file a already exists
1 out of 1 hunks FAILED -- saving rejects to file a.rej
abort: patch failed to apply
That's obviously correct: apply the same patch twice and the second
attempt fails.
But if the patch is slightly different, the behaviour is completely different:
$ cat patch2
diff --git a/b b/b
new file mode 100644
--- /dev/null
+++ b/b
$ hg patch --no-commit -f patch2
applying patch2
$ hg patch --no-commit -f patch2
applying patch2
It gets weirder:
$ echo foo > b
$ hg patch --no-commit -f patch2
applying patch2
That *really* should conflict. The patch wants b to be an empty file,
and it clearly isn't.
issue2135 reveals that transplant does not expect this inconsistent
behaviour, and ends up crashing as a result. I think there are two
bugs here:
* patch should fail when applying a patch that creates an empty
file, but the file already exists (empty or not)
* transplant should detect when its commit does nothing and crash
sooner rather than later
I'm going to take a look at patch.py and see if I can figure out a fix
for it. I already have a fix for the second problem -- will post it
shortly.
Greg
More information about the Mercurial-devel
mailing list