rebase: preserve mq series order, guarded patches (
issue2849)
The previous code was rebasing an applied series like:
patch1 +guarded
patch2
patch3 +guarded
patch4
patch5 +guarded
into:
patch2
patch4
patch1 +guarded
patch3 +guarded
patch5 +guarded
Reported by Lars Westerhoff <lars.westerhoff@newtec.eu>
Also rename mq.series_dirty into mq.seriesdirty, missed by
599a72895c0d, and
without effect since mq.qimport() was setting it already.
--- a/hgext/rebase.py Thu Apr 26 12:13:20 2012 +0200
+++ b/hgext/rebase.py Wed Apr 25 17:04:18 2012 +0200
@@ -446,6 +446,7 @@
mqrebase = {}
mq = repo.mq
original_series = mq.fullseries[:]
+ skippedpatches = set()
for p in mq.applied:
rev = repo[p.node].rev()
@@ -453,6 +454,9 @@
repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
(rev, p.name))
mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
+ else:
+ # Applied but not rebased, not sure this should happen
+ skippedpatches.add(p.name)
if mqrebase:
mq.finish(repo, mqrebase.keys())
@@ -464,14 +468,17 @@
repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
mq.qimport(repo, (), patchname=name, git=isgit,
rev=[str(state[rev])])
+ else:
+ # Rebased and skipped
+ skippedpatches.add(mqrebase[rev][0])
- # restore missing guards
- for s in original_series:
- pname = mq.guard_re.split(s, 1)[0]
- if pname in mq.fullseries:
- repo.ui.debug('restoring guard for patch %s' % (pname))
- mq.fullseries[mq.fullseries.index(pname)] = s
- mq.series_dirty = True
+ # Patches were either applied and rebased and imported in
+ # order, applied and removed or unapplied. Discard the removed
+ # ones while preserving the original series order and guards.
+ newseries = [s for s in original_series
+ if mq.guard_re.split(s, 1)[0] not in skippedpatches]
+ mq.fullseries[:] = newseries
+ mq.seriesdirty = True
mq.savedirty()
def updatebookmarks(repo, nstate, originalbookmarks, **opts):
--- a/tests/test-rebase-mq.t Thu Apr 26 12:13:20 2012 +0200
+++ b/tests/test-rebase-mq.t Wed Apr 25 17:04:18 2012 +0200
@@ -247,30 +247,41 @@
Create mq repo with guarded patches foo and bar and empty patch:
$ hg qinit
- $ hg qnew foo
- $ hg qguard foo +baz
+ $ echo guarded > guarded
+ $ hg add guarded
+ $ hg qnew guarded
+ $ hg qnew empty-important -m 'important commit message'
+ $ echo bar > bar
+ $ hg add bar
+ $ hg qnew bar
$ echo foo > foo
$ hg add foo
- $ hg qref
- $ hg qpop
+ $ hg qnew foo
+ $ hg qpop -a
popping foo
+ popping bar
+ popping empty-important
+ popping guarded
patch queue now empty
-
- $ hg qnew empty-important -m 'important commit message'
-
- $ hg qnew bar
+ $ hg qguard guarded +guarded
$ hg qguard bar +baz
- $ echo bar > bar
- $ hg add bar
- $ hg qref
+ $ hg qguard foo +baz
+ $ hg qselect baz
+ number of unguarded, unapplied patches has changed from 1 to 3
+ $ hg qpush bar
+ applying empty-important
+ patch empty-important is empty
+ applying bar
+ now at: bar
$ hg qguard -l
+ guarded: +guarded
empty-important: unguarded
bar: +baz
foo: +baz
$ hg tglog
- @ 2: '[mq]: bar' tags: bar qtip tip
+ @ 2: 'imported patch bar' tags: bar qtip tip
|
o 1: 'important commit message' tags: empty-important qbase
|
@@ -303,18 +314,21 @@
removed from the series):
$ hg qseries
+ guarded
empty-important
bar
foo
$ [ -f .hg/patches/empty-important ]
$ hg -q rebase -d 2
$ hg qseries
+ guarded
bar
foo
$ [ -f .hg/patches/empty-important ]
[1]
$ hg qguard -l
+ guarded: +guarded
bar: +baz
foo: +baz