[PATCH 3 of 6 topic-experiment] topics: update current topic to the topic of newly rebased commit (issue5551)

Pulkit Goyal 7895pulkit at gmail.com
Wed Jun 28 17:08:25 EDT 2017


# HG changeset patch
# User Pulkit Goyal <7895pulkit at gmail.com>
# Date 1498683715 -19800
#      Thu Jun 29 02:31:55 2017 +0530
# Node ID 95eb263307c3f8f514f1c9cb5e15b8d8284b418a
# Parent  dd6f7f7e8236eef7672b5ea1f22e6c34345217df
# EXP-Topic resolvetopic
topics: update current topic to the topic of newly rebased commit (issue5551)

The rebase code passes branchmerge equals to True while updating to the rebased
commit. We need to make sure topic is preserved even after rebase and hence we
need to update the topic even when branchmerge argument is set to True. But
there is a twist in the tale, merge also uses this part of code and we allow to
update topic when brancmerge is True, in merge cases the topic after merge will
the topic of the destination commit, not the topic of working directory parent.

So we need the function to have information about whether a rebase is going on,
and we do it by wrapping the rebase command and storing some value in the
config. This is a bit hacky but works for now. This patch fixes issue related to
loosing of topic while rebase.

Thanks to Boris Feld for the rigourous tests.

diff --git a/hgext3rd/topic/__init__.py b/hgext3rd/topic/__init__.py
--- a/hgext3rd/topic/__init__.py
+++ b/hgext3rd/topic/__init__.py
@@ -492,9 +492,17 @@
     matcher = kwargs.get('matcher')
     partial = not (matcher is None or matcher.always())
     wlock = repo.wlock()
+    isrebase = False
     try:
         ret = orig(repo, node, branchmerge, force, *args, **kwargs)
-        if not partial and not branchmerge:
+        # The mergeupdatewrap function makes the destination's topic as the
+        # current topic. This is right for merge but wrong for rebase. We check
+        # if rebase is running and update the currenttopic to topic of new
+        # rebased commit. We have explicitly stored in config if rebase is
+        # running.
+        if repo.ui.hasconfig('experimental', 'topicrebase'):
+            isrebase = True
+        if (not partial and not branchmerge) or isrebase:
             ot = repo.currenttopic
             t = ''
             pctx = repo[node]
@@ -519,9 +527,18 @@
     def newmakeextrafn(orig, copiers):
         return orig(copiers + [savetopic])
 
+    def setrebaseconfig(orig, ui, repo, **opts):
+        repo.ui.setconfig('experimental', 'topicrebase', 'yes',
+                          source='topic-extension')
+        return orig(ui, repo, **opts)
+
     try:
         rebase = extensions.find("rebase")
         extensions.wrapfunction(rebase, '_makeextrafn', newmakeextrafn)
+        # This exists to store in the config that rebase is running so that we can
+        # update the topic according to rebase. This is a hack and should be removed
+        # when we have better options.
+        extensions.wrapcommand(rebase.cmdtable, 'rebase', setrebaseconfig)
     except KeyError:
         pass
 
diff --git a/tests/test-topic-dest.t b/tests/test-topic-dest.t
--- a/tests/test-topic-dest.t
+++ b/tests/test-topic-dest.t
@@ -108,6 +108,7 @@
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg rebase
   rebasing 4:cb7ae72f4a80 "babar"
+  switching to topic elephant
   $ hg log -G
   @  7 (elephant) babar
   |
@@ -128,6 +129,7 @@
   1 files updated, 0 files merged, 3 files removed, 0 files unresolved
   $ hg rebase
   rebasing 5:d832ddc604ec "zephir"
+  switching to topic monkey
   $ hg log -G
   @  8 (monkey) zephir
   |
@@ -222,6 +224,7 @@
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg rebase -d 'desc(c_zeta)' # make sure tip is elsewhere
   rebasing 7:8d0b77140b05 "babar"
+  switching to topic elephant
   $ hg up monkey
   switching to topic monkey
   2 files updated, 0 files merged, 1 files removed, 0 files unresolved
diff --git a/tests/test-topic-rebase.t b/tests/test-topic-rebase.t
new file mode 100644
--- /dev/null
+++ b/tests/test-topic-rebase.t
@@ -0,0 +1,161 @@
+test of the rebase command
+--------------------------
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > split=-d "0 0"
+  > amend=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [ui]
+  > interactive = true
+  > [extensions]
+  > hgext.graphlog=
+  > rebase=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
+  $ echo "topic=$(echo $(dirname $TESTDIR))/hgext3rd/topic/" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1" $2 $3
+  > }
+  $ logtopic() {
+  >    hg log -G -T "{rev}:{node}\ntopics: {topics}" 
+  > }
+
+Check that rebase keep the topic in the simple case (1 changeset, no merge conflict)
+------------------------------------------------------------------------------------
+
+  $ hg init testrebase
+  $ cd testrebase
+  $ mkcommit ROOT
+
+Work on myfeature
+  $ hg topic myfeature
+  $ mkcommit feature1
+  $ hg stack
+  ### topic: myfeature
+  ### branch: default
+  t1@ add feature1 (current)
+    ^ add ROOT
+  $ logtopic
+  @  1:39e7a938055e87615edf675c24a10997ff05bb06
+  |  topics: myfeature
+  o  0:3e7df3b3b17c6deb4a1c70e790782fdf17af96a7
+     topics:
+
+Create another commit on default
+  $ hg update --rev default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit default
+  $ logtopic
+  @  2:be7622a7a0f43ba713e152f56441275f8e8711ef
+  |  topics:
+  | o  1:39e7a938055e87615edf675c24a10997ff05bb06
+  |/   topics: myfeature
+  o  0:3e7df3b3b17c6deb4a1c70e790782fdf17af96a7
+     topics:
+
+Rebase the commit
+  $ hg update --rev 1
+  switching to topic myfeature
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg rebase
+  rebasing 1:39e7a938055e "add feature1"
+  switching to topic myfeature
+  $ hg stack
+  ### topic: myfeature
+  ### branch: default
+  t1@ add feature1 (current)
+    ^ add default
+  $ logtopic
+  @  3:fc6593661cf3256ba165cbccd6019ead17cc3726
+  |  topics: myfeature
+  o  2:be7622a7a0f43ba713e152f56441275f8e8711ef
+  |  topics:
+  o  0:3e7df3b3b17c6deb4a1c70e790782fdf17af96a7
+     topics:
+  $ hg up 3
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg stack
+  ### topic: myfeature
+  ### branch: default
+  t1@ add feature1 (current)
+    ^ add default
+
+Check that rebase keep the topic in case of merge conflict
+----------------------------------------------------------
+
+Create a common base
+  $ hg topic --clear
+  $ echo "A" > file
+  $ hg commit -A -m "default2" file
+  created new head
+
+Update the common file in a topic
+  $ hg topic myotherfeature
+  $ echo "B" >> file
+  $ hg commit -m "myotherfeature1"
+
+Update the common file in default
+  $ hg update --rev default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo "A2" > file
+  $ hg commit -m "default3"
+
+Rebase the topic
+  $ hg update --rev 5
+  switching to topic myotherfeature
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg rebase
+  rebasing 5:81f854012ec5 "myotherfeature1"
+  merging file
+  warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
+  switching to topic myotherfeature
+  unresolved conflicts (see hg resolve, then hg rebase --continue)
+  [1]
+
+Resolve the conflict
+  $ echo "A2\nB" > file
+  $ hg resolve -m
+  (no more unresolved files)
+  continue: hg rebase --continue
+  $ hg rebase --continue
+  rebasing 5:81f854012ec5 "myotherfeature1"
+
+Check the the commit has the right topic
+
+  $ logtopic
+  @  7:6ccb9ec4913b64f3ad719ff1ba66495a70bf35a4
+  |  topics: myotherfeature
+  o  6:0b124ef641a7a6f4715d962650d3b367e8c800be
+  |  topics:
+  o  4:0cd2e1a45ac4e3f9603a05ccfa6d1c70cd759bc5
+  |  topics:
+  o  3:fc6593661cf3256ba165cbccd6019ead17cc3726
+  |  topics: myfeature
+  o  2:be7622a7a0f43ba713e152f56441275f8e8711ef
+  |  topics:
+  o  0:3e7df3b3b17c6deb4a1c70e790782fdf17af96a7
+     topics:
+  $ hg stack
+  ### topic: myotherfeature
+  ### branch: default
+  t1@ myotherfeature1 (current)
+    ^ default3
+  $ hg update --rev 7
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg stack
+  ### topic: myotherfeature
+  ### branch: default
+  t1@ myotherfeature1 (current)
+    ^ default3
diff --git a/tests/test-topic-tutorial.t b/tests/test-topic-tutorial.t
--- a/tests/test-topic-tutorial.t
+++ b/tests/test-topic-tutorial.t
@@ -243,6 +243,7 @@
   $ hg rebase
   rebasing 1:13900241408b "adding condiments"
   merging shopping
+  switching to topic food
   rebasing 2:287de11b401f "adding fruits"
   merging shopping
   $ hg log --graph
@@ -274,7 +275,7 @@
 The topic information will fade out when we publish the changesets::
 
   $ hg topic
-     food
+   * food
   $ hg push
   pushing to $TESTTMP/server (glob)
   searching for changes
@@ -284,6 +285,7 @@
   added 2 changesets with 2 changes to 1 files
   2 new obsolescence markers
   $ hg topic
+   * food
   $ hg log --graph
   @  changeset:   5:2d50db8b5b4c
   |  tag:         tip
@@ -405,6 +407,7 @@
   $ hg rebase
   rebasing 6:183984ef46d1 "Adding hammer"
   merging shopping
+  switching to topic tools
   rebasing 7:cffff85af537 "Adding saw"
   merging shopping
   rebasing 8:34255b455dac "Adding drill"
@@ -414,7 +417,7 @@
 
   $ hg topic --verbose
      drinks (on branch: default, 2 changesets, 2 behind)
-     tools  (on branch: default, 3 changesets)
+   * tools  (on branch: default, 3 changesets)
 
 The "2 behind" is telling you that there is 2 new changesets on the named branch of the topic. You need to merge or rebase to incorporate them.
 
@@ -433,6 +436,7 @@
   $ hg rebase -b drinks
   rebasing 9:8dfa45bd5e0c "Adding apple juice"
   merging shopping
+  switching to topic drinks
   rebasing 10:70dfa201ed73 "Adding orange juice"
   merging shopping
   switching to topic tools
diff --git a/tests/test-topic.t b/tests/test-topic.t
--- a/tests/test-topic.t
+++ b/tests/test-topic.t
@@ -630,12 +630,11 @@
   rebasing 12:18b70b8de1f0 "fran?"
   switching to topic wat
   $ hg topic
-   * wat
+     wat
 
   $ hg log -Gr 'draft()'
-  @  changeset:   14:503497a14c3e
+  @  changeset:   14:45358f7a5892
   |  tag:         tip
-  |  topic:       wat
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     fran?
@@ -653,7 +652,7 @@
   $ hg topic watwat
   $ hg ci --amend
   $ hg log -Gr 'draft()'
-  @  changeset:   16:024d9c69f30f
+  @  changeset:   16:6c40a4c21bbe
   |  tag:         tip
   |  topic:       watwat
   |  parent:      13:686a642006db
@@ -674,7 +673,7 @@
   $ hg topic --clear
   $ hg ci --amend
   $ hg log -r .
-  changeset:   18:573ab57c6de2
+  changeset:   18:0f9cd5070654
   tag:         tip
   parent:      13:686a642006db
   user:        test
@@ -690,7 +689,7 @@
   $ hg co 19
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg log -Gr 'draft()'
-  @  changeset:   19:2539ecb09b37
+  @  changeset:   19:980a0f608481
   |  tag:         tip
   |  topic:       watwat
   |  parent:      13:686a642006db
@@ -711,7 +710,7 @@
   changed topic on 2 changes
   please run hg evolve --rev "topic(changewat)" now
   $ hg log -Gr 'draft()'
-  @  changeset:   21:993d145391f5
+  @  changeset:   21:56c83be6105f
   |  tag:         tip
   |  topic:       changewat
   |  user:        test
@@ -743,7 +742,7 @@
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     gamma
   |
-  | o  changeset:   21:993d145391f5
+  | o  changeset:   21:56c83be6105f
   |/   topic:       changewat
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
@@ -769,7 +768,7 @@
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     gamma
   |
-  | o  changeset:   24:658ae31a0c05
+  | o  changeset:   24:369c6e2e5474
   |/   topic:       changewut
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000


More information about the Mercurial-devel mailing list