mq: preserve --git flag when merging patches stable
authorPatrick Mezard <pmezard@gmail.com>
Fri, 01 Jan 2010 19:53:05 +0100
branchstable
changeset 10185 7637fe4f525d
parent 10184 8a47347d298b
child 10186 296a0b14a686
mq: preserve --git flag when merging patches Without this, merging a patch queue without diff.git=1 downgrades all git patches to regular patches, losing data in the process.
hgext/mq.py
mercurial/mdiff.py
tests/test-mq-merge
tests/test-mq-merge.out
--- a/hgext/mq.py	Fri Jan 01 19:53:05 2010 +0100
+++ b/hgext/mq.py	Fri Jan 01 19:53:05 2010 +0100
@@ -261,12 +261,21 @@
     def diffopts(self, opts={}, patchfn=None):
         diffopts = patch.diffopts(self.ui, opts)
         if patchfn:
-            # if the patch was a git patch, refresh it as a git patch
-            patchf = self.opener(patchfn, 'r')
-            for line in patchf:
-                if line.startswith('diff --git'):
-                    diffopts.git = True
-                    break
+            diffopts = self.patchopts(diffopts, patchfn)
+        return diffopts
+
+    def patchopts(self, diffopts, patchfn):
+        """Return a copy of input diff options with git set to true if
+        referenced patch is a git patch.
+        """
+        diffopts = diffopts.copy()
+        patchf = self.opener(patchfn, 'r')
+        # if the patch was a git patch, refresh it as a git patch
+        for line in patchf:
+            if line.startswith('diff --git'):
+                diffopts.git = True
+                break
+        patchf.close()
         return diffopts
 
     def join(self, *p):
@@ -469,6 +478,7 @@
         except:
             raise util.Abort(_("unable to read %s") % patch)
 
+        diffopts = self.patchopts(diffopts, patch)
         patchf = self.opener(patch, "w")
         comments = str(ph)
         if comments:
--- a/mercurial/mdiff.py	Fri Jan 01 19:53:05 2010 +0100
+++ b/mercurial/mdiff.py	Fri Jan 01 19:53:05 2010 +0100
@@ -55,6 +55,11 @@
             raise util.Abort(_('diff context lines count must be '
                                'an integer, not %r') % self.context)
 
+    def copy(self, **kwargs):
+        opts = dict((k, getattr(self, k)) for k in self.defaults)
+        opts.update(kwargs)
+        return diffopts(**opts)
+
 defaultopts = diffopts()
 
 def wsclean(opts, text, blank=True):
--- a/tests/test-mq-merge	Fri Jan 01 19:53:05 2010 +0100
+++ b/tests/test-mq-merge	Fri Jan 01 19:53:05 2010 +0100
@@ -56,18 +56,27 @@
 echo % init t2
 hg init t2
 cd t2
+echo '[diff]' > .hg/hgrc
+echo 'nodates = 1' >> .hg/hgrc
 echo a > a
 hg ci -Am init
-echo b >> a
+echo b > a
 hg ci -m changea
 hg up -C 0
+hg cp a aa
 echo c >> a
-hg qnew -f -e patcha
+hg qnew --git -f -e patcha
+echo d >> a
+hg qnew -d '0 0' -f -e patcha2
 echo % create the reference queue
 hg qsave -c -e -n refqueue 2> /dev/null
 hg up -C 1
 echo % merge
-hg qpush -m -n refqueue 2>&1 | \
+HGMERGE=internal:other hg qpush -a -m -n refqueue 2>&1 | \
     sed 's/merging with queue at.*refqueue/merging with queue at refqueue/'
+echo % check patcha is still a git patch
+cat .hg/patches/patcha
+echo % check patcha2 is still a regular patch
+grep git .hg/patches/patcha2 && echo 'git patch found!'
 cd ..
 
--- a/tests/test-mq-merge.out	Fri Jan 01 19:53:05 2010 +0100
+++ b/tests/test-mq-merge.out	Fri Jan 01 19:53:05 2010 +0100
@@ -18,8 +18,35 @@
 adding a
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 % create the reference queue
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
 % merge
 merging with queue at refqueue
 applying patcha
-now at: patcha
+patching file a
+Hunk #1 FAILED at 0
+1 out of 1 hunks FAILED -- saving rejects to file a.rej
+patch failed, unable to continue (try -v)
+patch failed, rejects left in working dir
+patch didn't work out, merging patcha
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+0 files updated, 2 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+applying patcha2
+now at: patcha2
+% check patcha is still a git patch
+diff --git a/a b/a
+--- a/a
++++ b/a
+@@ -1,1 +1,2 @@
+-b
++a
++c
+diff --git a/a b/aa
+copy from a
+copy to aa
+--- a/a
++++ b/aa
+@@ -1,1 +1,1 @@
+-b
++a
+% check patcha2 is still a regular patch