<p dir="ltr">There's a topoiter or topoorder somewhere that is used by "hg log". Can that be used here? Sorry, on mobile and too lazy to find the exact function.</p>
<br><div class="gmail_quote"><div dir="ltr">On Sat, Sep 17, 2016, 08:18 Xidorn Quan <<a href="mailto:me@upsuper.org">me@upsuper.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br class="gmail_msg">
# User Xidorn Quan <<a href="mailto:me@upsuper.org" class="gmail_msg" target="_blank">me@upsuper.org</a>><br class="gmail_msg">
# Date 1474095776 -36000<br class="gmail_msg">
#      Sat Sep 17 17:02:56 2016 +1000<br class="gmail_msg">
# Node ID 88184dc23ccacfc8ae450abc5d574b8b028bca79<br class="gmail_msg">
# Parent  285a8c3e53f2183438f0cdbc238e4ab851d0d110<br class="gmail_msg">
rebase: rebase changesets with branch grouped<br class="gmail_msg">
<br class="gmail_msg">
diff --git a/hgext/rebase.py b/hgext/rebase.py<br class="gmail_msg">
--- a/hgext/rebase.py<br class="gmail_msg">
+++ b/hgext/rebase.py<br class="gmail_msg">
@@ -330,18 +330,38 @@ class rebaseruntime(object):<br class="gmail_msg">
                                                                inclusive=True)<br class="gmail_msg">
<br class="gmail_msg">
         # Keep track of the current bookmarks in order to reset them later<br class="gmail_msg">
         self.currentbookmarks = repo._bookmarks.copy()<br class="gmail_msg">
         self.activebookmark = self.activebookmark or repo._activebookmark<br class="gmail_msg">
         if self.activebookmark:<br class="gmail_msg">
             bookmarks.deactivate(repo)<br class="gmail_msg">
<br class="gmail_msg">
-        sortedrevs = sorted(self.state)<br class="gmail_msg">
+        # Sort revisions with branches grouped<br class="gmail_msg">
         cands = [k for k, v in self.state.iteritems() if v == revtodo]<br class="gmail_msg">
+        remainrevs = set(self.state.iterkeys())<br class="gmail_msg">
+        sortedrevs = []<br class="gmail_msg">
+        # Sort based on candidates and put their ancestors with them<br class="gmail_msg">
+        for cand in util.branchsorted(repo, cands):<br class="gmail_msg">
+            ancestors = [cand]<br class="gmail_msg">
+            remainrevs.remove(cand)<br class="gmail_msg">
+            i = 0<br class="gmail_msg">
+            while i < len(ancestors):<br class="gmail_msg">
+                ctx = repo[ancestors[i]]<br class="gmail_msg">
+                for p in ctx.parents():<br class="gmail_msg">
+                    prev = p.rev()<br class="gmail_msg">
+                    if prev in remainrevs:<br class="gmail_msg">
+                        remainrevs.remove(prev)<br class="gmail_msg">
+                        ancestors.append(prev)<br class="gmail_msg">
+                i += 1<br class="gmail_msg">
+            ancestors.reverse()<br class="gmail_msg">
+            sortedrevs.extend(ancestors)<br class="gmail_msg">
+        # Finally, descendents which are not rebased<br class="gmail_msg">
+        sortedrevs.extend(sorted(remainrevs))<br class="gmail_msg">
+<br class="gmail_msg">
         total = len(cands)<br class="gmail_msg">
         pos = 0<br class="gmail_msg">
         for rev in sortedrevs:<br class="gmail_msg">
             ctx = repo[rev]<br class="gmail_msg">
             desc = '%d:%s "%s"' % (ctx.rev(), ctx,<br class="gmail_msg">
                                    ctx.description().split('\n', 1)[0])<br class="gmail_msg">
             names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())<br class="gmail_msg">
             if names:<br class="gmail_msg">
diff --git a/mercurial/util.py b/mercurial/util.py<br class="gmail_msg">
--- a/mercurial/util.py<br class="gmail_msg">
+++ b/mercurial/util.py<br class="gmail_msg">
@@ -2897,8 +2897,33 @@ decompressors = {None: lambda fh: fh,<br class="gmail_msg">
                  'BZ': _makedecompressor(lambda: bz2.BZ2Decompressor()),<br class="gmail_msg">
                  'GZ': _makedecompressor(lambda: zlib.decompressobj()),<br class="gmail_msg">
                  }<br class="gmail_msg">
 # also support the old form by courtesies<br class="gmail_msg">
 decompressors['UN'] = decompressors[None]<br class="gmail_msg">
<br class="gmail_msg">
 # convenient shortcut<br class="gmail_msg">
 dst = debugstacktrace<br class="gmail_msg">
+<br class="gmail_msg">
+def branchsorted(repo, revs, sortrevs=None):<br class="gmail_msg">
+    '''Returns a sorted list of revisions in a order that branches are<br class="gmail_msg">
+    grouped together.'''<br class="gmail_msg">
+    remainrevs = set(revs)<br class="gmail_msg">
+    stack = [sorted(revs, reverse=True)]<br class="gmail_msg">
+    result = []<br class="gmail_msg">
+    while stack:<br class="gmail_msg">
+        stacktop = stack[-1]<br class="gmail_msg">
+        if not stacktop:<br class="gmail_msg">
+            stack.pop()<br class="gmail_msg">
+            continue<br class="gmail_msg">
+        nextrev = stacktop.pop()<br class="gmail_msg">
+        if nextrev not in remainrevs:<br class="gmail_msg">
+            continue<br class="gmail_msg">
+        ctx = repo[nextrev]<br class="gmail_msg">
+        # If any of its parents is still in remainrevs, we can not put<br class="gmail_msg">
+        # the changeset into result. We would traverse to it again when<br class="gmail_msg">
+        # we resolve all its parents.<br class="gmail_msg">
+        if any(p.rev() in remainrevs for p in ctx.parents()):<br class="gmail_msg">
+            continue<br class="gmail_msg">
+        remainrevs.remove(nextrev)<br class="gmail_msg">
+        result.append(nextrev)<br class="gmail_msg">
+        stack.append(sorted((c.rev() for c in ctx.children()), reverse=True))<br class="gmail_msg">
+    return result<br class="gmail_msg">
diff --git a/tests/test-rebase-branch-order.t b/tests/test-rebase-branch-order.t<br class="gmail_msg">
new file mode 100644<br class="gmail_msg">
--- /dev/null<br class="gmail_msg">
+++ b/tests/test-rebase-branch-order.t<br class="gmail_msg">
@@ -0,0 +1,89 @@<br class="gmail_msg">
+  $ cat >> $HGRCPATH <<EOF<br class="gmail_msg">
+  > [extensions]<br class="gmail_msg">
+  > rebase=<br class="gmail_msg">
+  > [alias]<br class="gmail_msg">
+  > tglog=log -G --template "{rev}:{node|short} {desc}"<br class="gmail_msg">
+  > EOF<br class="gmail_msg">
+<br class="gmail_msg">
+  $ hg init repo<br class="gmail_msg">
+  $ cd repo<br class="gmail_msg">
+<br class="gmail_msg">
+  $ touch a<br class="gmail_msg">
+  $ hg ci -Am A<br class="gmail_msg">
+  adding a<br class="gmail_msg">
+<br class="gmail_msg">
+  $ touch b<br class="gmail_msg">
+  $ hg ci -Am B<br class="gmail_msg">
+  adding b<br class="gmail_msg">
+<br class="gmail_msg">
+  $ touch c<br class="gmail_msg">
+  $ hg ci -Am C<br class="gmail_msg">
+  adding c<br class="gmail_msg">
+<br class="gmail_msg">
+  $ hg up 1<br class="gmail_msg">
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved<br class="gmail_msg">
+  $ touch d<br class="gmail_msg">
+  $ hg ci -Am D<br class="gmail_msg">
+  adding d<br class="gmail_msg">
+  created new head<br class="gmail_msg">
+<br class="gmail_msg">
+  $ hg up 2<br class="gmail_msg">
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved<br class="gmail_msg">
+  $ touch e<br class="gmail_msg">
+  $ hg ci -Am E<br class="gmail_msg">
+  adding e<br class="gmail_msg">
+<br class="gmail_msg">
+  $ hg up 3<br class="gmail_msg">
+  1 files updated, 0 files merged, 2 files removed, 0 files unresolved<br class="gmail_msg">
+  $ touch f<br class="gmail_msg">
+  $ hg ci -Am F<br class="gmail_msg">
+  adding f<br class="gmail_msg">
+<br class="gmail_msg">
+  $ hg up 0<br class="gmail_msg">
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved<br class="gmail_msg">
+  $ touch g<br class="gmail_msg">
+  $ hg ci -Am G<br class="gmail_msg">
+  adding g<br class="gmail_msg">
+  created new head<br class="gmail_msg">
+<br class="gmail_msg">
+  $ hg tglog<br class="gmail_msg">
+  @  6:124bb27b6f28 G<br class="gmail_msg">
+  |<br class="gmail_msg">
+  | o  5:412b391de760 F<br class="gmail_msg">
+  | |<br class="gmail_msg">
+  | | o  4:82ae8dc7a9b7 E<br class="gmail_msg">
+  | | |<br class="gmail_msg">
+  | o |  3:ab709c9f7171 D<br class="gmail_msg">
+  | | |<br class="gmail_msg">
+  | | o  2:d84f5cfaaf14 C<br class="gmail_msg">
+  | |/<br class="gmail_msg">
+  | o  1:76035bbd54bd B<br class="gmail_msg">
+  |/<br class="gmail_msg">
+  o  0:216878401574 A<br class="gmail_msg">
+<br class="gmail_msg">
+<br class="gmail_msg">
+Test rebasing is done with commits in branch grouped together.<br class="gmail_msg">
+<br class="gmail_msg">
+  $ hg rebase -s 1 -d 6<br class="gmail_msg">
+  rebasing 1:76035bbd54bd "B"<br class="gmail_msg">
+  rebasing 2:d84f5cfaaf14 "C"<br class="gmail_msg">
+  rebasing 4:82ae8dc7a9b7 "E"<br class="gmail_msg">
+  rebasing 3:ab709c9f7171 "D"<br class="gmail_msg">
+  rebasing 5:412b391de760 "F"<br class="gmail_msg">
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/76035bbd54bd-e341bc99-backup.hg (glob)<br class="gmail_msg">
+<br class="gmail_msg">
+  $ hg tglog<br class="gmail_msg">
+  o  6:31884cfb735e F<br class="gmail_msg">
+  |<br class="gmail_msg">
+  o  5:6d89fa5b0909 D<br class="gmail_msg">
+  |<br class="gmail_msg">
+  | o  4:de64d97c697b E<br class="gmail_msg">
+  | |<br class="gmail_msg">
+  | o  3:b18e4d2d0aa1 C<br class="gmail_msg">
+  |/<br class="gmail_msg">
+  o  2:0983daf9ff6a B<br class="gmail_msg">
+  |<br class="gmail_msg">
+  @  1:124bb27b6f28 G<br class="gmail_msg">
+  |<br class="gmail_msg">
+  o  0:216878401574 A<br class="gmail_msg">
+<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
Mercurial-devel mailing list<br class="gmail_msg">
<a href="mailto:Mercurial-devel@mercurial-scm.org" class="gmail_msg" target="_blank">Mercurial-devel@mercurial-scm.org</a><br class="gmail_msg">
<a href="https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel" rel="noreferrer" class="gmail_msg" target="_blank">https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel</a><br class="gmail_msg">
</blockquote></div>