# HG changeset patch # User Nicolas Dumazet # Date 1279295226 -32400 # Node ID 4f4b2b9c90fc272e12c01e596e61537d07749064 # Parent ba2520dd1e29e279e9130d26f646f5ba8934856f strip: support multiple revisions diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -513,7 +513,7 @@ # apply failed, strip away that rev and merge. hg.clean(repo, head) - self.strip(repo, n, update=False, backup='strip') + self.strip(repo, [n], update=False, backup='strip') ctx = repo[rev] ret = hg.merge(repo, rev) @@ -895,7 +895,7 @@ finally: release(wlock) - def strip(self, repo, rev, update=True, backup="all", force=None): + def strip(self, repo, revs, update=True, backup="all", force=None): wlock = lock = None try: wlock = repo.wlock() @@ -903,12 +903,13 @@ if update: self.check_localchanges(repo, force=force, refresh=False) - urev = self.qparents(repo, rev) + urev = self.qparents(repo, revs[0]) hg.clean(repo, urev) repo.dirstate.write() self.removeundo(repo) - repair.strip(self.ui, repo, rev, backup) + for rev in revs: + repair.strip(self.ui, repo, rev, backup) # strip may have unbundled a set of backed up revisions after # the actual strip self.removeundo(repo) @@ -1193,7 +1194,7 @@ for patch in reversed(self.applied[start:end]): self.ui.status(_("popping %s\n") % patch.name) del self.applied[start:end] - self.strip(repo, rev, update=False, backup='strip') + self.strip(repo, [rev], update=False, backup='strip') if self.applied: self.ui.write(_("now at: %s\n") % self.applied[-1].name) else: @@ -1373,7 +1374,7 @@ repo.dirstate.setparents(*cparents) self.applied.pop() self.applied_dirty = 1 - self.strip(repo, top, update=False, + self.strip(repo, [top], update=False, backup='strip') except: repo.dirstate.invalidate() @@ -1528,7 +1529,7 @@ update = True else: update = False - self.strip(repo, rev, update=update, backup='strip') + self.strip(repo, [rev], update=update, backup='strip') if qpp: self.ui.warn(_("saved queue repository parents: %s %s\n") % (short(qpp[0]), short(qpp[1]))) @@ -1915,7 +1916,7 @@ if qbase: ui.note(_('stripping applied patches from destination ' 'repository\n')) - dr.mq.strip(dr, qbase, update=False, backup=None) + dr.mq.strip(dr, [qbase], update=False, backup=None) if not opts['noupdate']: ui.note(_('updating destination repository\n')) hg.update(dr, dr.changelog.tip()) @@ -2377,8 +2378,8 @@ pass return 0 -def strip(ui, repo, rev, **opts): - """strip a changeset and all its descendants from the repository +def strip(ui, repo, *revs, **opts): + """strip changesets and all their descendants from the repository The strip command removes all changesets whose local revision number is greater than or equal to REV, and then restores any @@ -2407,18 +2408,21 @@ elif opts['nobackup']: backup = 'none' - rev = repo.lookup(rev) - p = repo.dirstate.parents() cl = repo.changelog - update = True - if p[0] == nullid: - update = False - elif p[1] == nullid and rev != cl.ancestor(p[0], rev): - update = False - elif rev not in (cl.ancestor(p[0], rev), cl.ancestor(p[1], rev)): - update = False + revs = set(cl.rev(repo.lookup(r)) for r in revs) - repo.mq.strip(repo, rev, backup=backup, update=update, force=opts['force']) + descendants = set(cl.descendants(*revs)) + strippedrevs = revs.union(descendants) + roots = revs.difference(descendants) + + update = False + for p in repo.dirstate.parents(): + if p != nullid and cl.rev(p) in strippedrevs: + update = True + break + + repo.mq.strip(repo, [cl.node(r) for r in roots], backup=backup, + update=update, force=opts['force']) return 0 def select(ui, repo, *args, **opts): @@ -2977,7 +2981,8 @@ ' number greater than REV which are not' ' descendants of REV (DEPRECATED)')), ('n', 'nobackup', None, _('no backups'))], - _('hg strip [-f] [-n] REV')), + ('r', 'rev', [], _('revisions to strip'), _('REV')), + _('hg strip [-f] [-n] REV...')), "qtop": (top, [] + seriesopts, _('hg qtop [-s]')), "qunapplied": (unapplied, diff --git a/tests/test-mq-strip b/tests/test-mq-strip --- a/tests/test-mq-strip +++ b/tests/test-mq-strip @@ -5,15 +5,18 @@ echo "[extensions]" >> $HGRCPATH echo "mq=" >> $HGRCPATH +restore() { + hg unbundle -q .hg/strip-backup/* + rm .hg/strip-backup/* +} teststrip() { hg up -C $1 echo % before update $1, strip $2 hg parents - hg strip $2 | hidebackup + hg --traceback strip $2 | hidebackup echo % after update $1, strip $2 hg parents - hg unbundle -q .hg/strip-backup/* - rm .hg/strip-backup/* + restore } hg init test @@ -53,3 +56,20 @@ hg strip 4 2>&1 | hidebackup echo % after strip of merge parent hg parents +restore + +echo "graphlog=" >> $HGRCPATH +hg up +hg glog +echo % 2 is parent of 3, only one strip should happen +hg strip 2 3 | hidebackup +hg glog +restore +hg glog +echo % 2 different branches: 2 strips +hg strip 2 4 | hidebackup +hg glog +restore +echo % 2 different branches and merge point: 1 strip +hg strip 1 2 4 | hidebackup +restore diff --git a/tests/test-mq-strip.out b/tests/test-mq-strip.out --- a/tests/test-mq-strip.out +++ b/tests/test-mq-strip.out @@ -165,3 +165,99 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: b +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +@ changeset: 4:264128213d29 +| tag: tip +| parent: 1:ef3a871183d7 +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: c +| +| o changeset: 3:443431ffac4f +| | user: test +| | date: Thu Jan 01 00:00:00 1970 +0000 +| | summary: e +| | +| o changeset: 2:65bd5f99a4a3 +|/ user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: d +| +o changeset: 1:ef3a871183d7 +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: b +| +o changeset: 0:9ab35a2d17cb + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: a + +% 2 is parent of 3, only one strip should happen +saved backup bundle to +@ changeset: 2:264128213d29 +| tag: tip +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: c +| +o changeset: 1:ef3a871183d7 +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: b +| +o changeset: 0:9ab35a2d17cb + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: a + +o changeset: 4:443431ffac4f +| tag: tip +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: e +| +o changeset: 3:65bd5f99a4a3 +| parent: 1:ef3a871183d7 +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: d +| +| @ changeset: 2:264128213d29 +|/ user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: c +| +o changeset: 1:ef3a871183d7 +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: b +| +o changeset: 0:9ab35a2d17cb + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: a + +% 2 different branches: 2 strips +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +saved backup bundle to +saved backup bundle to +o changeset: 2:65bd5f99a4a3 +| tag: tip +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: d +| +@ changeset: 1:ef3a871183d7 +| user: test +| date: Thu Jan 01 00:00:00 1970 +0000 +| summary: b +| +o changeset: 0:9ab35a2d17cb + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: a + +% 2 different branches and merge point: 1 strip +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +saved backup bundle to diff --git a/tests/test-mq.out b/tests/test-mq.out --- a/tests/test-mq.out +++ b/tests/test-mq.out @@ -59,7 +59,7 @@ qseries print the entire series file qtop print the name of the current patch qunapplied print the patches not yet applied - strip strip a changeset and all its descendants from the repository + strip strip changesets and all their descendants from the repository use "hg -v help mq" to show aliases and global options adding a