Mercurial > hg
changeset 10190:9c2c94934f0d
mq: upgrade to git patch when necessary (issue767)
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Fri, 01 Jan 2010 21:21:34 +0100 |
parents | e451e599fbcf |
children | 99d285ac5da4 |
files | hgext/mq.py tests/test-mq-eol tests/test-mq-eol.out tests/test-mq-git tests/test-mq-git.out tests/test-mq-merge tests/test-mq-qfold tests/test-mq.out |
diffstat | 8 files changed, 238 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/mq.py Fri Jan 01 20:54:05 2010 +0100 +++ b/hgext/mq.py Fri Jan 01 21:21:34 2010 +0100 @@ -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): @@ -1260,7 +1290,7 @@ patchf.write(chunk) try: - if diffopts.git: + if diffopts.git or diffopts.upgrade: copies = {} for dst in a: src = repo.dirstate.copied(dst)
--- a/tests/test-mq-eol Fri Jan 01 20:54:05 2010 +0100 +++ b/tests/test-mq-eol Fri Jan 01 21:21:34 2010 +0100 @@ -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 20:54:05 2010 +0100 +++ b/tests/test-mq-eol.out Fri Jan 01 21:21:34 2010 +0100 @@ -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 21:21:34 2010 +0100 @@ -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 21:21:34 2010 +0100 @@ -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 20:54:05 2010 +0100 +++ b/tests/test-mq-merge Fri Jan 01 21:21:34 2010 +0100 @@ -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-qfold Fri Jan 01 20:54:05 2010 +0100 +++ b/tests/test-mq-qfold Fri Jan 01 21:21:34 2010 +0100 @@ -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 20:54:05 2010 +0100 +++ b/tests/test-mq.out Fri Jan 01 21:21:34 2010 +0100 @@ -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