[PATCH 3 of 6 V3] histedit: replace various nodes lists with replacement graph (and issue3582)

Pierre-Yves David pierre-yves.david at logilab.fr
Wed Oct 10 11:45:08 CDT 2012


On Wed, Oct 10, 2012 at 10:54:36AM -0500, Augie Fackler wrote:
> (responding on the list for posterity)
> On Oct 10, 2012, at 3:59 AM, pierre-yves.david at logilab.fr wrote:
> 
> > @@ -140,30 +139,29 @@
> >> pick d36c0562f908 1 c
> >> pick 0efacef7cb48 3 f
> >> pick ae467701c500 2 d
> >> EOF
> >   $ hg histedit 1 --commands commands.txt --verbose | grep histedit
> > -  histedit: Should update metadata for the following changes:
> > -  histedit: moving bookmarks five from 0efacef7cb48 to 1be9c35b4cb2
> > +  histedit: moving bookmarks three from ae467701c500 to 1be9c35b4cb2
> >   histedit: moving bookmarks four from ae467701c500 to 1be9c35b4cb2
> > -  histedit: moving bookmarks three from ae467701c500 to 1be9c35b4cb2
> > +  histedit: moving bookmarks five from 0efacef7cb48 to 7c044e3e33a9
> >   saved backup bundle to $TESTTMP/r/.hg/strip-backup/ae467701c500-backup.hg (glob)
> > 
> > We expect 'five' to stay at tip, since the tipmost bookmark is most
> > likely the useful signal.
> > 
> >   $ hg log --graph
> >   @  changeset:   3:1be9c35b4cb2
> > -  |  bookmark:    five
> >   |  bookmark:    four
> >   |  bookmark:    three
> >   |  tag:         tip
> >   |  user:        test
> >   |  date:        Thu Jan 01 00:00:00 1970 +0000
> >   |  summary:     d
> >   |
> >   o  changeset:   2:7c044e3e33a9
> > +  |  bookmark:    five
> >   |  user:        test
> >   |  date:        Thu Jan 01 00:00:00 1970 +0000
> >   |  summary:     f
> >   |
> >   o  changeset:   1:d36c0562f908
> 
> 
> This change in test output isn't right: the workflow I use with histedit (which I should blog about) depends on tipmost bookmarks staying tipmost. I could be swayed that it's a defect for inactive bookmarks (I think), as that wouldn't break my particular workflow.
> 
> Other than that, this patch looks great, and I've queued the first two.

I totally missed that. I though it was movement related to the "bookmark on droped" fix.

That's a good example of "mixing multiple change is bad" (but hardly avoidable here).

I've a fixed version pullable from:

    http://hg-lab.logilab.org/wip/hg/#3fff2bdd0c44

The diff looks like

% 18:39 pyves at crater2 ~/src/mercurial-dev/tests > hg diff -r 9efd79c13b1f
diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -431,11 +431,11 @@ def histedit(ui, repo, *parent, **opts):
         replacements.extend(repl)
     elif opts.get('abort', False):
         if len(parent) != 0:
             raise util.Abort(_('no arguments allowed with --abort'))
         (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
-        mapping, tmpnodes, leafs = processreplacement(repo, replacements)
+        mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements)
         ui.debug('restore wc to old parent %s\n' % node.short(topmost))
         hg.clean(repo, topmost)
         cleanupnode(ui, repo, 'created', tmpnodes)
         cleanupnode(ui, repo, 'temp', leafs)
         os.unlink(os.path.join(repo.path, 'histedit-state'))
@@ -489,11 +489,11 @@ def histedit(ui, repo, *parent, **opts):
         parentctx, replacement_ = actfunc(ui, repo, parentctx, ha, opts)
         replacements.extend(replacement_)
 
     hg.update(repo, parentctx.node())
 
-    mapping, tmpnodes, created = processreplacement(repo, replacements)
+    mapping, tmpnodes, created, ntm = processreplacement(repo, replacements)
     if mapping:
         for prec, succs in mapping.iteritems():
             if not succs:
                 ui.debug('histedit: %s is dropped\n' % node.short(prec))
             else:
@@ -504,11 +504,11 @@ def histedit(ui, repo, *parent, **opts):
                     for n in succs[1:]:
                         ui.debug(m % node.short(n))
 
     if not keep:
         if mapping:
-            movebookmarks(ui, repo, mapping)
+            movebookmarks(ui, repo, mapping, topmost, ntm)
             # TODO update mq state
         cleanupnode(ui, repo, 'replaced', mapping)
 
     cleanupnode(ui, repo, 'temp', tmpnodes)
     os.unlink(os.path.join(repo.path, 'histedit-state'))
@@ -693,16 +693,38 @@ def processreplacement(repo, replacement
     # turn `final` into list (topologically sorted)
     nm = repo.changelog.nodemap
     for prec, succs in final.items():
         final[prec] = sorted(succs, key=nm.get)
 
-    return final, tmpnodes, new
+    # computed topmost element (necessary for bookmark)
+    if new:
+        newtopmost = max(new, key=repo.changelog.rev)
+    elif not final:
+        # Nothing rewritten at all. we won't need `newtopmost`
+        # It is the same as `oldtopmost` and `processreplacement` know it
+        newtopmost = None
+    else:
+        # every body died. The newtopmost is the parent of the root.
+        newtopmost = repo[min(final, key=repo.changelog.rev)].p1().node()
 
-def movebookmarks(ui, repo, mapping):
+    return final, tmpnodes, new, newtopmost
+
+def movebookmarks(ui, repo, mapping, oldtopmost, newtopmost):
     """Move bookmark from old to newly created node"""
+    if not mapping:
+        # if nothing got rewritten there is not purpose for this function
+        return
     moves = []
     for bk, old in repo._bookmarks.iteritems():
+        if old == oldtopmost:
+            # special case ensure bookmark stay on tip. 
+            #
+            # This is argually a feature and we may only want that for the
+            # active bookmark. But the behavior is kept compatible with the old
+            # version for now/
+            moves.append((bk, newtopmost))
+            continue
         base = old
         new = mapping.get(base, None)
         if new is None:
             continue
         while not new:
diff --git a/tests/test-histedit-bookmark-motion.t b/tests/test-histedit-bookmark-motion.t
--- a/tests/test-histedit-bookmark-motion.t
+++ b/tests/test-histedit-bookmark-motion.t
@@ -141,27 +141,27 @@
   > pick ae467701c500 2 d
   > EOF
   $ hg histedit 1 --commands commands.txt --verbose | grep histedit
   histedit: moving bookmarks three from ae467701c500 to 1be9c35b4cb2
   histedit: moving bookmarks four from ae467701c500 to 1be9c35b4cb2
-  histedit: moving bookmarks five from 0efacef7cb48 to 7c044e3e33a9
+  histedit: moving bookmarks five from 0efacef7cb48 to 1be9c35b4cb2
   saved backup bundle to $TESTTMP/r/.hg/strip-backup/ae467701c500-backup.hg (glob)
 
 We expect 'five' to stay at tip, since the tipmost bookmark is most
 likely the useful signal.
 
   $ hg log --graph
   @  changeset:   3:1be9c35b4cb2
+  |  bookmark:    five
   |  bookmark:    four
   |  bookmark:    three
   |  tag:         tip
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     d
   |
   o  changeset:   2:7c044e3e33a9
-  |  bookmark:    five
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     f
   |
   o  changeset:   1:d36c0562f908


-- 
Pierre-Yves David

http://www.logilab.fr/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20121010/fa73d5b7/attachment.pgp>


More information about the Mercurial-devel mailing list