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.
--- 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