mq: missing target files do not make qpush to fail immediately (issue 835)
Reported and explained by Peter Arrenbrecht <peter.arrenbrecht@gmail.com>.
Following file additions were skipped but empty files were still created. This situation could lead to qrefresh losing patch information.
--- a/mercurial/patch.py Tue Nov 27 23:55:03 2007 +0100
+++ b/mercurial/patch.py Sun Dec 02 13:53:29 2007 +0100
@@ -885,6 +885,19 @@
dopatch = True
gitworkdone = False
+ def getpatchfile(afile, bfile, hunk):
+ try:
+ if sourcefile:
+ targetfile = patchfile(ui, sourcefile)
+ else:
+ targetfile = selectfile(afile, bfile, hunk,
+ strip, reverse)
+ targetfile = patchfile(ui, targetfile)
+ return targetfile
+ except PatchError, err:
+ ui.warn(str(err) + '\n')
+ return None
+
while True:
newfile = False
x = lr.readline()
@@ -912,22 +925,20 @@
continue
hunknum += 1
if not current_file:
- if sourcefile:
- current_file = patchfile(ui, sourcefile)
- else:
- current_file = selectfile(afile, bfile, current_hunk,
- strip, reverse)
- current_file = patchfile(ui, current_file)
+ current_file = getpatchfile(afile, bfile, current_hunk)
+ if not current_file:
+ current_file, current_hunk = None, None
+ rejects += 1
+ continue
elif state == BFILE and x.startswith('GIT binary patch'):
current_hunk = binhunk(changed[bfile[2:]][1])
+ hunknum += 1
if not current_file:
- if sourcefile:
- current_file = patchfile(ui, sourcefile)
- else:
- current_file = selectfile(afile, bfile, current_hunk,
- strip, reverse)
- current_file = patchfile(ui, current_file)
- hunknum += 1
+ current_file = getpatchfile(afile, bfile, current_hunk)
+ if not current_file:
+ current_file, current_hunk = None, None
+ rejects += 1
+ continue
current_hunk.extract(fp)
elif x.startswith('diff --git'):
# check for git diff, scanning the whole patch file if needed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-missingfiles Sun Dec 02 13:53:29 2007 +0100
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+# Test issue835:
+# qpush fails immediately when patching a missing file, but
+# remaining added files are still created empty which will
+# trick a future qrefresh.
+
+cat > writelines.py <<EOF
+import sys
+path = sys.argv[1]
+args = sys.argv[2:]
+assert (len(args) % 2) == 0
+
+f = file(path, 'wb')
+for i in xrange(len(args)/2):
+ count, s = args[2*i:2*i+2]
+ count = int(count)
+ s = s.decode('string_escape')
+ f.write(s*count)
+f.close()
+
+EOF
+
+echo "[extensions]" >> $HGRCPATH
+echo "mq=" >> $HGRCPATH
+
+hg init normal
+cd normal
+python ../writelines.py b 10 'a\n'
+hg ci -Am addb
+echo a > a
+python ../writelines.py b 2 'b\n' 10 'a\n' 2 'c\n'
+echo c > c
+hg add a c
+hg qnew -f changeb
+hg qpop
+hg rm b
+hg ci -Am rmb
+echo % push patch with missing target
+hg qpush
+echo % display added files
+cat a
+cat c
+cd ..
+
+
+echo "[diff]" >> $HGRCPATH
+echo "git=1" >> $HGRCPATH
+
+hg init git
+cd git
+python ../writelines.py b 1 '\x00'
+hg ci -Am addb
+echo a > a
+python ../writelines.py b 1 '\x01' 1 '\x00'
+echo c > c
+hg add a c
+hg qnew -f changeb
+hg qpop
+hg rm b
+hg ci -Am rmb
+echo % push git patch with missing target
+hg qpush 2>&1 | sed -e 's/b:.*/b: No such file or directory/'
+hg st
+echo % display added files
+cat a
+cat c
+cd ..
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-missingfiles.out Sun Dec 02 13:53:29 2007 +0100
@@ -0,0 +1,25 @@
+adding b
+Patch queue now empty
+% push patch with missing target
+applying changeb
+unable to find b or b for patching
+unable to find b or b for patching
+patch failed, unable to continue (try -v)
+patch failed, rejects left in working dir
+Errors during apply, please fix and refresh changeb
+% display added files
+a
+c
+adding b
+Patch queue now empty
+% push git patch with missing target
+applying changeb
+unable to find b or b for patching
+patch failed, unable to continue (try -v)
+b: No such file or directory
+b not tracked!
+patch failed, rejects left in working dir
+Errors during apply, please fix and refresh changeb
+% display added files
+a
+c