Commits

Patrick Mézard  committed f597421

obsolete: unify collapsed revisions markers handling

When collapsing A, B and C into D, amend was registering:

A -> D
B -> D
A -> B
C -> D
A -> C

while the rebase wrapper was doing:

A -> D
B -> D
C -> D

At this point, I have no argument to favor one or another or even a new
one like:

A -> B
B -> C
C -> D

so I am aligning the rebase implementation on the older amend one. At
least we can now change them all at once.

  • Participants
  • Parent commits 590ac02
  • Branches default

Comments (0)

Files changed (3)

File hgext/evolve.py

                 bookmarks.write(repo)
 
             # add evolution metadata
-            repo.addobsolete(new.node(), old.node())
-            for u in updates:
-                repo.addobsolete(u.node(), old.node())
-                repo.addobsolete(new.node(), u.node())
+            collapsed = set([u.node() for u in updates] + [old.node()])
+            repo.addcollapsedobsolete(collapsed, new.node())
             oldbookmarks = repo.nodebookmarks(old.node())
             for book in oldbookmarks:
                 repo._bookmarks[book] = new.node()

File hgext/obsolete.py

         repo._rebasestate = dict(p for p in repo._rebasestate.iteritems()
                                  if p[1] >= 0)
         if not res and not kwargs.get('abort') and repo._rebasestate:
-            # We have to tell rewritten revisions from removed
-            # ones. When collapsing, removed revisions are considered
-            # to be collapsed onto the final one, while in the normal
-            # case their are marked obsolete without successor.
-            emptynode = nullid
-            if kwargs.get('collapse'):
-                emptynode = repo[max(repo._rebasestate.values())].node()
             # Rebased revisions are assumed to be descendants of
             # targetrev. If a source revision is mapped to targetrev
             # or to another rebased revision, it must have been
             # removed.
             targetrev = repo[repo._rebasetarget].rev()
             newrevs = set([targetrev])
+            replacements = {}
             for rev, newrev in sorted(repo._rebasestate.items()):
                 oldnode = repo[rev].node()
                 if newrev not in newrevs:
                     newnode = repo[newrev].node()
                     newrevs.add(newrev)
                 else:
-                    newnode = emptynode
-                repo.addobsolete(newnode, oldnode)
+                    newnode = nullid
+                replacements[oldnode] = newnode
+
+            if kwargs.get('collapse'):
+                newnodes = set(n for n in replacements.values() if n != nullid)
+                if newnodes:
+                    # Collapsing into more than one revision?
+                    assert len(newnodes) == 1, newnodes
+                    newnode = newnodes.pop()
+                else:
+                    newnode = nullid
+                repo.addcollapsedobsolete(replacements, newnode)
+            else:
+                for oldnode, newnode in replacements.iteritems():
+                    repo.addobsolete(newnode, oldnode)
         return res
     finally:
         delattr(repo, '_rebasestate')
             finally:
                 lock.release()
 
+        def addcollapsedobsolete(self, oldnodes, newnode):
+            """Mark oldnodes as collapsed into newnode."""
+            # Assume oldnodes are all descendants of a single rev
+            rootrevs = self.revs('roots(%ln)', oldnodes)
+            assert len(rootrevs) == 1, rootrevs
+            rootnode = self[rootrevs[0]].node()
+            for n in oldnodes:
+                if n != rootnode:
+                    self.addobsolete(n, rootnode)
+                self.addobsolete(newnode, n)
+
         def _turn_extinct_secret(self):
             """ensure all extinct changeset are secret"""
             self._clearobsoletecache()

File tests/test-obsolete-rebase.t

   
   $ hg debugsuccessors
   03f31481307a a7773ffa7edc
+  076e9b2ffbe1 03f31481307a
   076e9b2ffbe1 a7773ffa7edc
   4e322f7ce8e3 000000000000
   98e4a024635e 9c5494949763
   $ diff -u ../successors.old ../successors.new
   --- ../successors.old* (glob)
   +++ ../successors.new* (glob)
-  @@ -1,4 +1,6 @@
+  @@ -1,5 +1,7 @@
    03f31481307a a7773ffa7edc
+   076e9b2ffbe1 03f31481307a
    076e9b2ffbe1 a7773ffa7edc
   +4b9d80f48523 1951ead97108
    4e322f7ce8e3 000000000000