[PATCH stable] strip: enhance repair.strip to receive a list of nodes (issue3299)
Matt Mackall
mpm at selenic.com
Mon Mar 12 13:09:56 CDT 2012
On Fri, 2012-03-09 at 19:35 -0300, Wagner Bruna wrote:
> # HG changeset patch
> # User Wagner Bruna <wbruna at softwareexpress.com.br>
> # Date 1331328992 10800
> # Branch stable
> # Node ID 4c8010f21d300c95e9498fc678bda2c471c67e63
> # Parent ce292f1379bad02a6478fee0aff8ce8ae8a3ee82
> strip: enhance repair.strip to receive a list of nodes (issue3299)
> Originally, mq.strip called repair.strip a single rev at a time.
> repair.strip stores in a backup bundle any revision greater than
> the revision being stripped, strips, then restores the backup with
> repo.addchangegroup. So, when stripping revisions on more than one
> topological branch, some could end up being restored from the backup
> bundle, only to be later removed by a subsequent repair.strip call.
While I like the fix, it's going to potentially break strip-using
extensions, which makes it less ideal for the stable branch. Can we use
an isinstance here?
> But repo.addchangegroup calls hooks for all those restore operations.
> And 9df9444e96ec changed it to delay all hook calls until the
> repository lock were released - by mq.strip, after stripping all
> revisions. Thus, the hooks could be called over revisions already
> removed from the repository at that point.
>
> By generating the revision lists at once inside repo.strip, we avoid
> calling addchangegroup for temporary restores. Incidentally, this
> also avoids creating many backup files for a single strip command.
>
> diff --git a/hgext/mq.py b/hgext/mq.py
> --- a/hgext/mq.py
> +++ b/hgext/mq.py
> @@ -1043,8 +1043,7 @@ class queue(object):
> repo.dirstate.write()
>
> self.removeundo(repo)
> - for rev in revs:
> - repair.strip(self.ui, repo, rev, backup)
> + repair.strip(self.ui, repo, revs, backup)
> # strip may have unbundled a set of backed up revisions after
> # the actual strip
> self.removeundo(repo)
> diff --git a/hgext/rebase.py b/hgext/rebase.py
> --- a/hgext/rebase.py
> +++ b/hgext/rebase.py
> @@ -325,7 +325,7 @@ def rebase(ui, repo, **opts):
> "on source branch, not stripping\n"))
> else:
> # backup the old csets by default
> - repair.strip(ui, repo, repo[min(rebased)].node(), "all")
> + repair.strip(ui, repo, [repo[min(rebased)].node()], "all")
>
> if currentbookmarks:
> updatebookmarks(repo, nstate, currentbookmarks, **opts)
> @@ -574,7 +574,7 @@ def abort(repo, originalwd, target, stat
> if rebased:
> strippoint = min(rebased)
> # no backup of rebased cset versions needed
> - repair.strip(repo.ui, repo, repo[strippoint].node())
> + repair.strip(repo.ui, repo, [repo[strippoint].node()])
> clearstatus(repo)
> repo.ui.warn(_('rebase aborted\n'))
> return 0
> diff --git a/mercurial/repair.py b/mercurial/repair.py
> --- a/mercurial/repair.py
> +++ b/mercurial/repair.py
> @@ -54,10 +54,11 @@ def _collectbrokencsets(repo, files, str
>
> return s
>
> -def strip(ui, repo, node, backup="all"):
> +def strip(ui, repo, nodelist, backup="all"):
> cl = repo.changelog
> # TODO delete the undo files, and handle undo of merge sets
> - striprev = cl.rev(node)
> + striplist = [cl.rev(node) for node in nodelist]
> + striprev = min(striplist)
>
> keeppartialbundle = backup == 'strip'
>
> @@ -68,8 +69,10 @@ def strip(ui, repo, node, backup="all"):
> # the list of heads and bases of the set of interesting revisions.
> # (head = revision in the set that has no descendant in the set;
> # base = revision in the set that has no ancestor in the set)
> - tostrip = set(cl.descendants(striprev))
> - tostrip.add(striprev)
> + tostrip = set(striplist)
> + for rev in striplist:
> + for desc in cl.descendants(rev):
> + tostrip.add(desc)
>
> files = _collectfiles(repo, striprev)
> saverevs = _collectbrokencsets(repo, files, striprev)
> @@ -88,6 +91,7 @@ def strip(ui, repo, node, backup="all"):
> descendants = set(cl.descendants(*saverevs))
> saverevs.difference_update(descendants)
> savebases = [cl.node(r) for r in saverevs]
> + stripbases = [cl.node(r) for r in tostrip]
>
> bm = repo._bookmarks
> updatebm = []
> @@ -99,7 +103,7 @@ def strip(ui, repo, node, backup="all"):
> # create a changegroup for all the branches we need to keep
> backupfile = None
> if backup == "all":
> - backupfile = _bundle(repo, [node], cl.heads(), node, 'backup')
> + backupfile = _bundle(repo, stripbases, cl.heads(), node, 'backup')
> repo.ui.status(_("saved backup bundle to %s\n") % backupfile)
> if saveheads or savebases:
> # do not compress partial bundle if we remove it from disk later
> diff --git a/tests/test-mq-strip.t b/tests/test-mq-strip.t
> --- a/tests/test-mq-strip.t
> +++ b/tests/test-mq-strip.t
> @@ -311,7 +311,6 @@ 2 different branches: 2 strips
> $ hg strip 2 4
> 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
> - saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
> $ hg glog
> @ changeset: 2:65bd5f99a4a3
> | tag: tip
> @@ -421,3 +420,13 @@ Verify strip protects against stripping
> $ hg status
> M bar
> ? b
> + $ cd ..
> +
> +stripping many nodes on a complex graph (issue3299)
> +
> + $ hg init issue3299
> + $ cd issue3299
> + $ hg debugbuilddag '@a.:a at b.:b.:x<a at a.:a<b at b.:b<a at a.:a'
> + $ hg strip 'not ancestors(x)'
> + saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
> +
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list