D6331: log: add config for making `hg log -G` always topo-sorted

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Wed May 1 17:22:29 UTC 2019


martinvonz created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  I (and everyone else at Google) have an log alias that adds graph mode
  and templating. I have another one that builds on the first and also
  restricts the set of revisions to only show those I'm most likely to
  care about. This second alias also adds topological sorting. I still
  sometimes use the first one. When I do, it very often bothers me that
  it's not topologically sorted (branches are interleaved). This patch
  adds a config option for always using topological sorting with graph
  log.
  
  The revision set is sorted eagerly, which seems like a bad idea, but
  it doesn't seem to make a big difference in the hg repo (150ms). I
  initially tried to instead wrap the user's revset in sort(...,topo),
  but that seemed much harder.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D6331

AFFECTED FILES
  mercurial/configitems.py
  mercurial/logcmdutil.py
  tests/test-glog-topological.t

CHANGE DETAILS

diff --git a/tests/test-glog-topological.t b/tests/test-glog-topological.t
--- a/tests/test-glog-topological.t
+++ b/tests/test-glog-topological.t
@@ -114,3 +114,41 @@
   |/
   o  0
   
+
+Topological sort can be turned on via config
+
+  $ cat >> $HGRCPATH << EOF
+  > [experimental]
+  > log.topo=true
+  > EOF
+
+  $ hg log -G
+  o  8
+  |
+  o  3
+  |
+  o  2
+  |
+  o  1
+  |
+  | o  7
+  | |
+  | o  6
+  | |
+  | o  5
+  | |
+  | o  4
+  |/
+  o  0
+  
+Does not affect non-graph log
+  $ hg log -T '{rev}\n'
+  8
+  7
+  6
+  5
+  4
+  3
+  2
+  1
+  0
diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -717,6 +717,13 @@
         revs.reverse()
     return revs
 
+def _maybetoposort(repo, revs, opts):
+    if opts.get('graph') and repo.ui.configbool('experimental', 'log.topo'):
+        revs = dagop.toposort(revs, repo.changelog.parentrevs)
+        # TODO: try to iterate the set lazily
+        revs = revset.baseset(list(revs))
+    return revs
+
 def getrevs(repo, pats, opts):
     """Return (revs, differ) where revs is a smartset
 
@@ -727,7 +734,7 @@
     limit = getlimit(opts)
     revs = _initialrevs(repo, opts)
     if not revs:
-        return smartset.baseset(), None
+        return _maybetoposort(repo, smartset.baseset(), opts), None
     match, pats, slowpath = _makematcher(repo, revs, pats, opts)
     filematcher = None
     if follow:
@@ -756,7 +763,7 @@
 
     differ = changesetdiffer()
     differ._makefilematcher = filematcher
-    return revs, differ
+    return _maybetoposort(repo, revs, opts), differ
 
 def _parselinerangeopt(repo, opts):
     """Parse --line-range log option and return a list of tuples (filename,
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -532,6 +532,9 @@
 coreconfigitem('experimental', 'evolution.track-operation',
     default=True,
 )
+coreconfigitem('experimental', 'log.topo',
+    default=False,
+)
 coreconfigitem('experimental', 'maxdeltachainspan',
     default=-1,
 )



To: martinvonz, #hg-reviewers
Cc: mjpieters, mercurial-devel


More information about the Mercurial-devel mailing list