mq: missing target files do not make qpush to fail immediately (issue 835)
authorPatrick Mezard <pmezard@gmail.com>
Sun, 02 Dec 2007 13:53:29 +0100
changeset 5581 8a8c341bd292
parent 5549 f2f42262adbd
child 5582 60d46e0bd656
child 5584 d2831a5d5947
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.
mercurial/patch.py
tests/test-mq-missingfiles
tests/test-mq-missingfiles.out
--- 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