[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