--- a/hgext/mq.py Fri Jan 01 15:33:51 2010 -0600
+++ b/hgext/mq.py Fri Jan 01 15:45:48 2010 -0600
@@ -26,6 +26,18 @@
add known patch to applied stack qpush
remove patch from applied stack qpop
refresh contents of top applied patch qrefresh
+
+By default, mq will automatically use git patches when required to
+avoid losing file mode changes, copy records, binary files or empty
+files creations or deletions. This behaviour can be configured with::
+
+ [mq]
+ git = auto/keep/yes/no
+
+If set to 'keep', mq will obey the [diff] section configuration while
+preserving existing git patches upon qrefresh. If set to 'yes' or
+'no', mq will override the [diff] section and always generate git or
+regular patches, possibly losing data in the second case.
'''
from mercurial.i18n import _
@@ -225,6 +237,14 @@
self.guards_path = "guards"
self.active_guards = None
self.guards_dirty = False
+ # Handle mq.git as a bool with extended values
+ try:
+ gitmode = ui.configbool('mq', 'git', None)
+ if gitmode is None:
+ raise error.ConfigError()
+ self.gitmode = gitmode and 'yes' or 'no'
+ except error.ConfigError:
+ self.gitmode = ui.config('mq', 'git', 'auto').lower()
@util.propertycache
def applied(self):
@@ -260,23 +280,33 @@
def diffopts(self, opts={}, patchfn=None):
diffopts = patch.diffopts(self.ui, opts)
+ if self.gitmode == 'auto':
+ diffopts.upgrade = True
+ elif self.gitmode == 'keep':
+ pass
+ elif self.gitmode in ('yes', 'no'):
+ diffopts.git = self.gitmode == 'yes'
+ else:
+ raise util.Abort(_('mq.git option can be auto/keep/yes/no'
+ ' got %s') % self.gitmode)
if patchfn:
diffopts = self.patchopts(diffopts, patchfn)
return diffopts
def patchopts(self, diffopts, *patches):
"""Return a copy of input diff options with git set to true if
- referenced patch is a git patch.
+ referenced patch is a git patch and should be preserved as such.
"""
diffopts = diffopts.copy()
- for patchfn in patches:
- 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()
+ if not diffopts.git and self.gitmode == 'keep':
+ for patchfn in patches:
+ 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):
@@ -741,11 +771,13 @@
def check_toppatch(self, repo):
if len(self.applied) > 0:
top = bin(self.applied[-1].rev)
+ patch = self.applied[-1].name
pp = repo.dirstate.parents()
if top not in pp:
raise util.Abort(_("working directory revision is not qtip"))
- return top
- return None
+ return top, patch
+ return None, None
+
def check_localchanges(self, repo, force=False, refresh=True):
m, a, r, d = repo.status()[:4]
if m or a or r or d:
@@ -1095,7 +1127,7 @@
end = len(self.applied)
rev = bin(self.applied[start].rev)
if update:
- top = self.check_toppatch(repo)
+ top = self.check_toppatch(repo)[0]
try:
heads = repo.changelog.heads(rev)
@@ -1144,7 +1176,7 @@
wlock.release()
def diff(self, repo, pats, opts):
- top = self.check_toppatch(repo)
+ top, patch = self.check_toppatch(repo)
if not top:
self.ui.write(_("no patches applied\n"))
return
@@ -1153,7 +1185,7 @@
node1, node2 = None, qp
else:
node1, node2 = qp, None
- diffopts = self.diffopts(opts)
+ diffopts = self.diffopts(opts, patch)
self.printdiff(repo, diffopts, node1, node2, files=pats, opts=opts)
def refresh(self, repo, pats=None, **opts):
@@ -1183,14 +1215,6 @@
if newdate:
ph.setdate(newdate)
- # 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'):
- self.diffopts().git = True
- break
- patchf.close()
-
# only commit new patch when write is complete
patchf = self.opener(patchfn, 'w', atomictemp=True)
@@ -1268,7 +1292,7 @@
patchf.write(chunk)
try:
- if diffopts.git:
+ if diffopts.git or diffopts.upgrade:
copies = {}
for dst in a:
src = repo.dirstate.copied(dst)
@@ -2036,7 +2060,7 @@
if not files:
raise util.Abort(_('qfold requires at least one patch name'))
- if not q.check_toppatch(repo):
+ if not q.check_toppatch(repo)[0]:
raise util.Abort(_('No patches applied'))
q.check_localchanges(repo)
--- a/mercurial/mdiff.py Fri Jan 01 15:33:51 2010 -0600
+++ b/mercurial/mdiff.py Fri Jan 01 15:45:48 2010 -0600
@@ -27,7 +27,9 @@
nodates removes dates from diff headers
ignorews ignores all whitespace changes in the diff
ignorewsamount ignores changes in the amount of whitespace
- ignoreblanklines ignores changes whose lines are all blank'''
+ ignoreblanklines ignores changes whose lines are all blank
+ upgrade generates git diffs to avoid data loss
+ '''
defaults = {
'context': 3,
@@ -38,6 +40,7 @@
'ignorews': False,
'ignorewsamount': False,
'ignoreblanklines': False,
+ 'upgrade': False,
}
__slots__ = defaults.keys()
--- a/mercurial/patch.py Fri Jan 01 15:33:51 2010 -0600
+++ b/mercurial/patch.py Fri Jan 01 15:45:48 2010 -0600
@@ -1246,17 +1246,25 @@
ret.append('\n')
return ''.join(ret)
-def _addmodehdr(header, omode, nmode):
- if omode != nmode:
- header.append('old mode %s\n' % omode)
- header.append('new mode %s\n' % nmode)
+class GitDiffRequired(Exception):
+ pass
-def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None):
+def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None,
+ losedatafn=None):
'''yields diff of changes to files between two nodes, or node and
working directory.
if node1 is None, use first dirstate parent instead.
- if node2 is None, compare node1 with working directory.'''
+ if node2 is None, compare node1 with working directory.
+
+ losedatafn(**kwarg) is a callable run when opts.upgrade=True and
+ every time some change cannot be represented with the current
+ patch format. Return False to upgrade to git patch format, True to
+ accept the loss or raise an exception to abort the diff. It is
+ called with the name of current file being diffed as 'fn'. If set
+ to None, patches will always be upgraded to git format when
+ necessary.
+ '''
if opts is None:
opts = mdiff.defaultopts
@@ -1288,24 +1296,50 @@
modified, added, removed = changes[:3]
if not modified and not added and not removed:
- return
+ return []
+
+ revs = None
+ if not repo.ui.quiet:
+ hexfunc = repo.ui.debugflag and hex or short
+ revs = [hexfunc(node) for node in [node1, node2] if node]
+
+ copy = {}
+ if opts.git or opts.upgrade:
+ copy = copies.copies(repo, ctx1, ctx2, repo[nullid])[0]
+ copy = copy.copy()
+ for k, v in copy.items():
+ copy[v] = k
+
+ difffn = lambda opts, losedata: trydiff(repo, revs, ctx1, ctx2,
+ modified, added, removed, copy, getfilectx, opts, losedata)
+ if opts.upgrade and not opts.git:
+ try:
+ def losedata(fn):
+ if not losedatafn or not losedatafn(fn=fn):
+ raise GitDiffRequired()
+ # Buffer the whole output until we are sure it can be generated
+ return list(difffn(opts.copy(git=False), losedata))
+ except GitDiffRequired:
+ return difffn(opts.copy(git=True), None)
+ else:
+ return difffn(opts, None)
+
+def _addmodehdr(header, omode, nmode):
+ if omode != nmode:
+ header.append('old mode %s\n' % omode)
+ header.append('new mode %s\n' % nmode)
+
+def trydiff(repo, revs, ctx1, ctx2, modified, added, removed,
+ copy, getfilectx, opts, losedatafn):
date1 = util.datestr(ctx1.date())
man1 = ctx1.manifest()
- revs = None
- if not repo.ui.quiet and not opts.git:
- hexfunc = repo.ui.debugflag and hex or short
- revs = [hexfunc(node) for node in [node1, node2] if node]
+ gone = set()
+ gitmode = {'l': '120000', 'x': '100755', '': '100644'}
if opts.git:
- copy, diverge = copies.copies(repo, ctx1, ctx2, repo[nullid])
- copy = copy.copy()
- for k, v in copy.items():
- copy[v] = k
-
- gone = set()
- gitmode = {'l': '120000', 'x': '100755', '': '100644'}
+ revs = None
for f in sorted(modified + added + removed):
to = None
@@ -1317,39 +1351,61 @@
if f not in removed:
tn = getfilectx(f, ctx2).data()
a, b = f, f
- if opts.git:
+ if opts.git or losedatafn:
if f in added:
mode = gitmode[ctx2.flags(f)]
if f in copy:
- a = copy[f]
- omode = gitmode[man1.flags(a)]
- _addmodehdr(header, omode, mode)
- if a in removed and a not in gone:
- op = 'rename'
- gone.add(a)
+ if opts.git:
+ a = copy[f]
+ omode = gitmode[man1.flags(a)]
+ _addmodehdr(header, omode, mode)
+ if a in removed and a not in gone:
+ op = 'rename'
+ gone.add(a)
+ else:
+ op = 'copy'
+ header.append('%s from %s\n' % (op, a))
+ header.append('%s to %s\n' % (op, f))
+ to = getfilectx(a, ctx1).data()
else:
- op = 'copy'
- header.append('%s from %s\n' % (op, a))
- header.append('%s to %s\n' % (op, f))
- to = getfilectx(a, ctx1).data()
+ losedatafn(f)
else:
- header.append('new file mode %s\n' % mode)
+ if opts.git:
+ header.append('new file mode %s\n' % mode)
+ elif ctx2.flags(f):
+ losedatafn(f)
if util.binary(tn):
- dodiff = 'binary'
+ if opts.git:
+ dodiff = 'binary'
+ else:
+ losedatafn(f)
+ if not opts.git and not tn:
+ # regular diffs cannot represent new empty file
+ losedatafn(f)
elif f in removed:
- # have we already reported a copy above?
- if f in copy and copy[f] in added and copy[copy[f]] == f:
- dodiff = False
- else:
- header.append('deleted file mode %s\n' %
- gitmode[man1.flags(f)])
+ if opts.git:
+ # have we already reported a copy above?
+ if f in copy and copy[f] in added and copy[copy[f]] == f:
+ dodiff = False
+ else:
+ header.append('deleted file mode %s\n' %
+ gitmode[man1.flags(f)])
+ elif not to:
+ # regular diffs cannot represent empty file deletion
+ losedatafn(f)
else:
- omode = gitmode[man1.flags(f)]
- nmode = gitmode[ctx2.flags(f)]
- _addmodehdr(header, omode, nmode)
- if util.binary(to) or util.binary(tn):
- dodiff = 'binary'
- header.insert(0, mdiff.diffline(revs, a, b, opts))
+ oflag = man1.flags(f)
+ nflag = ctx2.flags(f)
+ binary = util.binary(to) or util.binary(tn)
+ if opts.git:
+ _addmodehdr(header, gitmode[oflag], gitmode[nflag])
+ if binary:
+ dodiff = 'binary'
+ elif binary or nflag != oflag:
+ losedatafn(f)
+ if opts.git:
+ header.insert(0, mdiff.diffline(revs, a, b, opts))
+
if dodiff:
if dodiff == 'binary':
text = b85diff(to, tn)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/autodiff.py Fri Jan 01 15:45:48 2010 -0600
@@ -0,0 +1,46 @@
+# Extension dedicated to test patch.diff() upgrade modes
+#
+#
+from mercurial import cmdutil, patch, util
+
+def autodiff(ui, repo, *pats, **opts):
+ diffopts = patch.diffopts(ui, opts)
+ git = opts.get('git', 'no')
+ brokenfiles = set()
+ losedatafn = None
+ if git in ('yes', 'no'):
+ diffopts.git = git == 'yes'
+ diffopts.upgrade = False
+ elif git == 'auto':
+ diffopts.git = False
+ diffopts.upgrade = True
+ elif git == 'warn':
+ diffopts.git = False
+ diffopts.upgrade = True
+ def losedatafn(fn=None, **kwargs):
+ brokenfiles.add(fn)
+ return True
+ elif git == 'abort':
+ diffopts.git = False
+ diffopts.upgrade = True
+ def losedatafn(fn=None, **kwargs):
+ raise util.Abort('losing data for %s' % fn)
+ else:
+ raise util.Abort('--git must be yes, no or auto')
+
+ node1, node2 = cmdutil.revpair(repo, [])
+ m = cmdutil.match(repo, pats, opts)
+ it = patch.diff(repo, node1, node2, match=m, opts=diffopts,
+ losedatafn=losedatafn)
+ for chunk in it:
+ ui.write(chunk)
+ for fn in sorted(brokenfiles):
+ ui.write('data lost for: %s\n' % fn)
+
+cmdtable = {
+ "autodiff":
+ (autodiff,
+ [('', 'git', '', 'git upgrade mode (yes/no/auto/warn/abort)'),
+ ],
+ '[OPTION]... [FILE]...'),
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-diff-upgrade Fri Jan 01 15:45:48 2010 -0600
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+echo "[extensions]" >> $HGRCPATH
+echo "autodiff=$TESTDIR/autodiff.py" >> $HGRCPATH
+echo "[diff]" >> $HGRCPATH
+echo "nodates=1" >> $HGRCPATH
+
+hg init repo
+cd repo
+echo '% make a combination of new, changed and deleted file'
+echo regular > regular
+echo rmregular > rmregular
+touch rmempty
+echo exec > exec
+chmod +x exec
+echo rmexec > rmexec
+chmod +x rmexec
+echo setexec > setexec
+echo unsetexec > unsetexec
+chmod +x unsetexec
+echo binary > binary
+python -c "file('rmbinary', 'wb').write('\0')"
+hg ci -Am addfiles
+echo regular >> regular
+echo newregular >> newregular
+rm rmempty
+touch newempty
+rm rmregular
+echo exec >> exec
+echo newexec > newexec
+chmod +x newexec
+rm rmexec
+chmod +x setexec
+chmod -x unsetexec
+python -c "file('binary', 'wb').write('\0\0')"
+python -c "file('newbinary', 'wb').write('\0')"
+rm rmbinary
+hg addremove
+
+echo '% git=no: regular diff for all files'
+hg autodiff --git=no
+
+echo '% git=no: git diff for single regular file'
+hg autodiff --git=yes regular
+
+echo '% git=auto: regular diff for regular files and removals'
+hg autodiff --git=auto regular newregular rmregular rmbinary rmexec
+
+for f in exec newexec setexec unsetexec binary newbinary newempty rmempty; do
+ echo '% git=auto: git diff for' $f
+ hg autodiff --git=auto $f
+done
+
+echo '% git=warn: regular diff with data loss warnings'
+hg autodiff --git=warn
+
+echo '% git=abort: fail on execute bit change'
+hg autodiff --git=abort regular setexec
+
+echo '% git=abort: succeed on regular file'
+hg autodiff --git=abort regular
+
+cd ..
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-diff-upgrade.out Fri Jan 01 15:45:48 2010 -0600
@@ -0,0 +1,186 @@
+% make a combination of new, changed and deleted file
+adding binary
+adding exec
+adding regular
+adding rmbinary
+adding rmempty
+adding rmexec
+adding rmregular
+adding setexec
+adding unsetexec
+adding newbinary
+adding newempty
+adding newexec
+adding newregular
+removing rmbinary
+removing rmempty
+removing rmexec
+removing rmregular
+% git=no: regular diff for all files
+diff -r b3f053cd7c7f binary
+Binary file binary has changed
+diff -r b3f053cd7c7f exec
+--- a/exec
++++ b/exec
+@@ -1,1 +1,2 @@
+ exec
++exec
+diff -r b3f053cd7c7f newbinary
+Binary file newbinary has changed
+diff -r b3f053cd7c7f newexec
+--- /dev/null
++++ b/newexec
+@@ -0,0 +1,1 @@
++newexec
+diff -r b3f053cd7c7f newregular
+--- /dev/null
++++ b/newregular
+@@ -0,0 +1,1 @@
++newregular
+diff -r b3f053cd7c7f regular
+--- a/regular
++++ b/regular
+@@ -1,1 +1,2 @@
+ regular
++regular
+diff -r b3f053cd7c7f rmbinary
+Binary file rmbinary has changed
+diff -r b3f053cd7c7f rmexec
+--- a/rmexec
++++ /dev/null
+@@ -1,1 +0,0 @@
+-rmexec
+diff -r b3f053cd7c7f rmregular
+--- a/rmregular
++++ /dev/null
+@@ -1,1 +0,0 @@
+-rmregular
+% git=no: git diff for single regular file
+diff --git a/regular b/regular
+--- a/regular
++++ b/regular
+@@ -1,1 +1,2 @@
+ regular
++regular
+% git=auto: regular diff for regular files and removals
+diff -r b3f053cd7c7f newregular
+--- /dev/null
++++ b/newregular
+@@ -0,0 +1,1 @@
++newregular
+diff -r b3f053cd7c7f regular
+--- a/regular
++++ b/regular
+@@ -1,1 +1,2 @@
+ regular
++regular
+diff -r b3f053cd7c7f rmbinary
+Binary file rmbinary has changed
+diff -r b3f053cd7c7f rmexec
+--- a/rmexec
++++ /dev/null
+@@ -1,1 +0,0 @@
+-rmexec
+diff -r b3f053cd7c7f rmregular
+--- a/rmregular
++++ /dev/null
+@@ -1,1 +0,0 @@
+-rmregular
+% git=auto: git diff for exec
+diff -r b3f053cd7c7f exec
+--- a/exec
++++ b/exec
+@@ -1,1 +1,2 @@
+ exec
++exec
+% git=auto: git diff for newexec
+diff --git a/newexec b/newexec
+new file mode 100755
+--- /dev/null
++++ b/newexec
+@@ -0,0 +1,1 @@
++newexec
+% git=auto: git diff for setexec
+diff --git a/setexec b/setexec
+old mode 100644
+new mode 100755
+% git=auto: git diff for unsetexec
+diff --git a/unsetexec b/unsetexec
+old mode 100755
+new mode 100644
+% git=auto: git diff for binary
+diff --git a/binary b/binary
+index a9128c283485202893f5af379dd9beccb6e79486..09f370e38f498a462e1ca0faa724559b6630c04f
+GIT binary patch
+literal 2
+Jc${Nk0000200961
+
+% git=auto: git diff for newbinary
+diff --git a/newbinary b/newbinary
+new file mode 100644
+index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d
+GIT binary patch
+literal 1
+Ic${MZ000310RR91
+
+% git=auto: git diff for newempty
+diff --git a/newempty b/newempty
+new file mode 100644
+% git=auto: git diff for rmempty
+diff --git a/rmempty b/rmempty
+deleted file mode 100644
+% git=warn: regular diff with data loss warnings
+diff -r b3f053cd7c7f binary
+Binary file binary has changed
+diff -r b3f053cd7c7f exec
+--- a/exec
++++ b/exec
+@@ -1,1 +1,2 @@
+ exec
++exec
+diff -r b3f053cd7c7f newbinary
+Binary file newbinary has changed
+diff -r b3f053cd7c7f newexec
+--- /dev/null
++++ b/newexec
+@@ -0,0 +1,1 @@
++newexec
+diff -r b3f053cd7c7f newregular
+--- /dev/null
++++ b/newregular
+@@ -0,0 +1,1 @@
++newregular
+diff -r b3f053cd7c7f regular
+--- a/regular
++++ b/regular
+@@ -1,1 +1,2 @@
+ regular
++regular
+diff -r b3f053cd7c7f rmbinary
+Binary file rmbinary has changed
+diff -r b3f053cd7c7f rmexec
+--- a/rmexec
++++ /dev/null
+@@ -1,1 +0,0 @@
+-rmexec
+diff -r b3f053cd7c7f rmregular
+--- a/rmregular
++++ /dev/null
+@@ -1,1 +0,0 @@
+-rmregular
+data lost for: binary
+data lost for: newbinary
+data lost for: newempty
+data lost for: newexec
+data lost for: rmempty
+data lost for: setexec
+data lost for: unsetexec
+% git=abort: fail on execute bit change
+abort: losing data for setexec
+% git=abort: succeed on regular file
+diff -r b3f053cd7c7f regular
+--- a/regular
++++ b/regular
+@@ -1,1 +1,2 @@
+ regular
++regular
--- a/tests/test-mq-eol Fri Jan 01 15:33:51 2010 -0600
+++ b/tests/test-mq-eol Fri Jan 01 15:45:48 2010 -0600
@@ -4,6 +4,8 @@
echo "[extensions]" >> $HGRCPATH
echo "mq=" >> $HGRCPATH
+echo "[diff]" >> $HGRCPATH
+echo "nodates=1" >> $HGRCPATH
cat > makepatch.py <<EOF
f = file('eol.diff', 'wb')
--- a/tests/test-mq-eol.out Fri Jan 01 15:33:51 2010 -0600
+++ b/tests/test-mq-eol.out Fri Jan 01 15:45:48 2010 -0600
@@ -23,7 +23,7 @@
now at: eol.diff
test message<LF>
<LF>
-diff --git a/a b/a<LF>
+diff -r 0d0bf99a8b7a a<LF>
--- a/a<LF>
+++ b/a<LF>
@@ -1,5 +1,5 @@<LF>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-git Fri Jan 01 15:45:48 2010 -0600
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# Test the plumbing of mq.git option
+# Automatic upgrade itself is tested elsewhere.
+
+echo "[extensions]" >> $HGRCPATH
+echo "mq=" >> $HGRCPATH
+echo "[diff]" >> $HGRCPATH
+echo "nodates=1" >> $HGRCPATH
+
+hg init repo-auto
+cd repo-auto
+echo '% git=auto: regular patch creation'
+echo a > a
+hg add a
+hg qnew -d '0 0' -f adda
+cat .hg/patches/adda
+echo '% git=auto: git patch creation with copy'
+hg cp a b
+hg qnew -d '0 0' -f copy
+cat .hg/patches/copy
+echo '% git=auto: git patch when using --git'
+echo regular > regular
+hg add regular
+hg qnew -d '0 0' --git -f git
+cat .hg/patches/git
+echo '% git=auto: regular patch after qrefresh without --git'
+hg qrefresh -d '0 0'
+cat .hg/patches/git
+cd ..
+
+hg init repo-keep
+cd repo-keep
+echo '[mq]' > .hg/hgrc
+echo 'git = KEEP' >> .hg/hgrc
+echo '% git=keep: git patch with --git'
+echo a > a
+hg add a
+hg qnew -d '0 0' -f --git git
+cat .hg/patches/git
+echo '% git=keep: git patch after qrefresh without --git'
+echo a >> a
+hg qrefresh -d '0 0'
+cat .hg/patches/git
+cd ..
+
+hg init repo-yes
+cd repo-yes
+echo '[mq]' > .hg/hgrc
+echo 'git = yes' >> .hg/hgrc
+echo '% git=yes: git patch'
+echo a > a
+hg add a
+hg qnew -d '0 0' -f git
+cat .hg/patches/git
+echo '% git=yes: git patch after qrefresh'
+echo a >> a
+hg qrefresh -d '0 0'
+cat .hg/patches/git
+cd ..
+
+hg init repo-no
+cd repo-no
+echo '[diff]' > .hg/hgrc
+echo 'git = True' >> .hg/hgrc
+echo '[mq]' > .hg/hgrc
+echo 'git = False' >> .hg/hgrc
+echo '% git=no: regular patch with copy'
+echo a > a
+hg add a
+hg qnew -d '0 0' -f adda
+hg cp a b
+hg qnew -d '0 0' -f regular
+cat .hg/patches/regular
+echo '% git=no: regular patch after qrefresh with copy'
+hg cp a c
+hg qrefresh -d '0 0'
+cat .hg/patches/regular
+cd ..
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-git.out Fri Jan 01 15:45:48 2010 -0600
@@ -0,0 +1,100 @@
+% git=auto: regular patch creation
+# HG changeset patch
+# Date 0 0
+
+diff -r 000000000000 -r ef8dafc9fa4c a
+--- /dev/null
++++ b/a
+@@ -0,0 +1,1 @@
++a
+% git=auto: git patch creation with copy
+# HG changeset patch
+# Date 0 0
+
+diff --git a/a b/b
+copy from a
+copy to b
+% git=auto: git patch when using --git
+# HG changeset patch
+# Date 0 0
+
+diff --git a/regular b/regular
+new file mode 100644
+--- /dev/null
++++ b/regular
+@@ -0,0 +1,1 @@
++regular
+% git=auto: regular patch after qrefresh without --git
+# HG changeset patch
+# Date 0 0
+
+diff -r 2962f232b49d regular
+--- /dev/null
++++ b/regular
+@@ -0,0 +1,1 @@
++regular
+% git=keep: git patch with --git
+# HG changeset patch
+# Date 0 0
+
+diff --git a/a b/a
+new file mode 100644
+--- /dev/null
++++ b/a
+@@ -0,0 +1,1 @@
++a
+% git=keep: git patch after qrefresh without --git
+# HG changeset patch
+# Date 0 0
+
+diff --git a/a b/a
+new file mode 100644
+--- /dev/null
++++ b/a
+@@ -0,0 +1,2 @@
++a
++a
+% git=yes: git patch
+# HG changeset patch
+# Date 0 0
+
+diff --git a/a b/a
+new file mode 100644
+--- /dev/null
++++ b/a
+@@ -0,0 +1,1 @@
++a
+% git=yes: git patch after qrefresh
+# HG changeset patch
+# Date 0 0
+
+diff --git a/a b/a
+new file mode 100644
+--- /dev/null
++++ b/a
+@@ -0,0 +1,2 @@
++a
++a
+% git=no: regular patch with copy
+# HG changeset patch
+# Date 0 0
+
+diff -r ef8dafc9fa4c -r 110cde11d262 b
+--- /dev/null
++++ b/b
+@@ -0,0 +1,1 @@
++a
+% git=no: regular patch after qrefresh with copy
+# HG changeset patch
+# Date 0 0
+
+diff -r ef8dafc9fa4c b
+--- /dev/null
++++ b/b
+@@ -0,0 +1,1 @@
++a
+diff -r ef8dafc9fa4c c
+--- /dev/null
++++ b/c
+@@ -0,0 +1,1 @@
++a
--- a/tests/test-mq-merge Fri Jan 01 15:33:51 2010 -0600
+++ b/tests/test-mq-merge Fri Jan 01 15:45:48 2010 -0600
@@ -16,6 +16,8 @@
echo "[extensions]" >> $HGRCPATH
echo "mq =" >> $HGRCPATH
+echo "[mq]" >> $HGRCPATH
+echo "git = keep" >> $HGRCPATH
# Commit two dummy files in "init" changeset
hg init t
--- a/tests/test-mq-qdiff Fri Jan 01 15:33:51 2010 -0600
+++ b/tests/test-mq-qdiff Fri Jan 01 15:45:48 2010 -0600
@@ -2,6 +2,8 @@
echo "[extensions]" >> $HGRCPATH
echo "mq=" >> $HGRCPATH
+echo "[mq]" >> $HGRCPATH
+echo "git=keep" >> $HGRCPATH
echo % init
hg init a
@@ -60,3 +62,9 @@
echo % qdiff --reverse
hg qdiff --nodates --reverse
+
+echo % qdiff preserve existing git flag
+hg qrefresh --git
+echo a >> lines
+hg qdiff
+
--- a/tests/test-mq-qdiff.out Fri Jan 01 15:33:51 2010 -0600
+++ b/tests/test-mq-qdiff.out Fri Jan 01 15:45:48 2010 -0600
@@ -103,3 +103,22 @@
7
8
9
+% qdiff preserve existing git flag
+diff --git a/lines b/lines
+--- a/lines
++++ b/lines
+@@ -1,9 +1,12 @@
++
++
+ 1
+ 2
+ 3
+ 4
+-hello world
+-goodbye world
++hello world
++ goodbye world
+ 7
+ 8
+ 9
++a
--- a/tests/test-mq-qfold Fri Jan 01 15:33:51 2010 -0600
+++ b/tests/test-mq-qfold Fri Jan 01 15:45:48 2010 -0600
@@ -2,6 +2,8 @@
echo "[extensions]" >> $HGRCPATH
echo "mq=" >> $HGRCPATH
+echo "[mq]" >> $HGRCPATH
+echo "git=keep" >> $HGRCPATH
filterdiff()
{
--- a/tests/test-mq.out Fri Jan 01 15:33:51 2010 -0600
+++ b/tests/test-mq.out Fri Jan 01 15:45:48 2010 -0600
@@ -21,6 +21,18 @@
remove patch from applied stack qpop
refresh contents of top applied patch qrefresh
+By default, mq will automatically use git patches when required to avoid
+losing file mode changes, copy records, binary files or empty files creations
+or deletions. This behaviour can be configured with:
+
+ [mq]
+ git = auto/keep/yes/no
+
+If set to 'keep', mq will obey the [diff] section configuration while
+preserving existing git patches upon qrefresh. If set to 'yes' or 'no', mq
+will override the [diff] section and always generate git or regular patches,
+possibly losing data in the second case.
+
list of commands:
qapplied print the patches already applied