[PATCH 2 of 4 topic-experiment] topics: wrap the movetoprev function from evolve to change behaviour of prev

Pulkit Goyal 7895pulkit at gmail.com
Tue Jul 4 10:29:22 EDT 2017


# HG changeset patch
# User Pulkit Goyal <7895pulkit at gmail.com>
# Date 1499124408 -19800
#      Tue Jul 04 04:56:48 2017 +0530
# Node ID 3a1fb8ffae6836d11c410c94e00adb0079b764f6
# Parent  143abe59c2d630461718ea0ea6277ab16abd9637
topics: wrap the movetoprev function from evolve to change behaviour of prev

After this commit, if you do `hg prev` from t1, it will take you to t0 and will
preserve the topics. Also if you have a topic active and that's different from
the topic of current commit, you will be taken to the last commit of that topic.
I am still not convinced about the behaviour mentioned in last statement and
needs a second approval before things get into.

diff --git a/hgext3rd/topic/__init__.py b/hgext3rd/topic/__init__.py
--- a/hgext3rd/topic/__init__.py
+++ b/hgext3rd/topic/__init__.py
@@ -189,6 +189,7 @@
     try:
         evolve = extensions.find('evolve')
         extensions.wrapfunction(evolve, "presplitupdate", presplitupdatetopic)
+        extensions.wrapfunction(evolve, "movetoprev", prevwithtopic)
     except (KeyError, AttributeError):
         pass
 
@@ -538,6 +539,42 @@
                           source='topic-extension')
     return orig(ui, repo, node, rev, clean, date, check, merge, tool)
 
+def prevwithtopic(orig, ui, repo, parents, opts):
+    # XXX: If the topic we are on has different commit than the current topic,
+    # then the behaviour can be buggy(needs dicussion to think what the default
+    # behaviour should be)
+    if opts.get('no_topic'):
+        return orig(ui, repo, parents, opts)
+    ctx = repo[None].parents()[0]
+    revnum = ctx.rev()
+    curtopic = repo.currenttopic
+    if not curtopic:
+        curtopic = ctx.topic()
+    # There is no topic on the current changeset and no current topic, so we
+    # should switch to default behaviour.
+    if not curtopic:
+        return orig(ui, repo, parents, opts)
+    # Firstly relying on current topic as t0 will have a different topic. If
+    # `hg prev` will be called from t0, that will change the topic and update
+    # to parent of t0 having the same topic as t0, so that's buggy. But if there
+    # is not current topic, we can take the topic of that changeset into account
+    # as there won't be any possibility of t0.
+    revlist = stack.getstack(repo, topic=curtopic)
+    try:
+        idx = revlist.index(revnum)
+    except IndexError:
+        # Lets move to the last ctx of the current topic
+        idx = len(revlist)
+    if idx == 0:
+        msg = _('no more changesets in topic "%s"')
+        raise error.Abort(msg % curtopic)
+    parentrev = revlist[idx - 1]
+    if idx == 1:
+        repo.ui.setconfig('experimental', 'updatingtot0', 'yes',
+                          source='topic-extension')
+    topicparent = [repo[parentrev]]
+    return orig(ui, repo, topicparent, opts)
+
 def _fixrebase(loaded):
     if not loaded:
         return
diff --git a/tests/test-evolve-topic.t b/tests/test-evolve-topic.t
--- a/tests/test-evolve-topic.t
+++ b/tests/test-evolve-topic.t
@@ -209,9 +209,10 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   [16] add ggg
   $ hg prev
-  switching to topic foo
+  preserving the current topic 'bar'
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   [15] add fff
   $ hg prev --no-topic
+  switching to topic foo
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   [14] add eee


More information about the Mercurial-devel mailing list