Patchwork [evolve-ext] touch: prompt the user for what to do with the revived changeset

login
register
mail settings
Submitter Laurent Charignon
Date Jan. 18, 2016, 12:56 a.m.
Message ID <2186330ccab5a527c8e9.1453078594@lcharignon-mbp.local>
Download mbox | patch
Permalink /patch/12823/
State Accepted
Delegated to: Pierre-Yves David
Headers show

Comments

Laurent Charignon - Jan. 18, 2016, 12:56 a.m.
# HG changeset patch
# User Laurent Charignon <lcharignon@fb.com>
# Date 1453078540 28800
#      Sun Jan 17 16:55:40 2016 -0800
# Node ID 2186330ccab5a527c8e92fc4acc46c39d238ae7a
# Parent  4f83b2d2d20de55b2a63910ff10204af9106fd26
touch: prompt the user for what to do with the revived changeset

This patch improves our interface for reviving changesets.
This patch makes touch not assume that the user wants to create divergence by
default and gives a prompt instead. The prompt is skipped for changeset that
have no living successor as no divergence would be created by reviving them
anyway.

To restore the previous behavior, one should now use the --allowdivergence flag.
The prompt looks like:

[10] <description>
reviving this changeset will create divergence unless you make a duplicate.
(a)llow divergence or (d)uplicate the changeset?  a

In further patches we will want to add one more choice to that prompt, for
example having a marker between the old and revived nodes but no divergence
displayed on the UI.
Pierre-Yves David - Jan. 30, 2016, 3:24 p.m.
On 01/18/2016 01:56 AM, Laurent Charignon wrote:
> # HG changeset patch
> # User Laurent Charignon <lcharignon@fb.com>
> # Date 1453078540 28800
> #      Sun Jan 17 16:55:40 2016 -0800
> # Node ID 2186330ccab5a527c8e92fc4acc46c39d238ae7a
> # Parent  4f83b2d2d20de55b2a63910ff10204af9106fd26
> touch: prompt the user for what to do with the revived changeset

I'm not super excited about the UI, but this is a significant 
improvement. Lets take it as we don't garantee any UI BC.

Patch

diff --git a/hgext/evolve.py b/hgext/evolve.py
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -2819,7 +2819,10 @@  def stripwrapper(orig, ui, repo, *revs, 
 @command('^touch',
     [('r', 'rev', [], 'revision to update'),
      ('D', 'duplicate', False,
-      'do not mark the new revision as successor of the old one')],
+      'do not mark the new revision as successor of the old one'),
+     ('A', 'allowdivergence', False,
+      'mark the new revision as successor of the old one potentially creating '
+      'divergence')],
     # allow to choose the seed ?
     _('[-r] revs'))
 def touch(ui, repo, *revs, **opts):
@@ -2829,6 +2832,7 @@  def touch(ui, repo, *revs, **opts):
     This is used to "resurrect" changesets
     """
     duplicate = opts['duplicate']
+    allowdivergence = opts['allowdivergence']
     revs = list(revs)
     revs.extend(opts['rev'])
     if not revs:
@@ -2839,6 +2843,7 @@  def touch(ui, repo, *revs, **opts):
         return 1
     if not duplicate and repo.revs('public() and %ld', revs):
         raise error.Abort("can't touch public revision")
+    displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
     wlock = lock = tr = None
     try:
         wlock = repo.wlock()
@@ -2855,11 +2860,37 @@  def touch(ui, repo, *revs, **opts):
             p2 = ctx.p2().node()
             p1 = newmapping.get(p1, p1)
             p2 = newmapping.get(p2, p2)
+
+            if not (duplicate or allowdivergence):
+                # The user hasn't yet decided what to do with the revived
+                # cset, let's ask
+                sset = obsolete.successorssets(repo, ctx.node())
+                nodivergencerisk = len(sset) == 0 or (
+                                    len(sset) == 1 and
+                                    len(sset[0]) == 1 and
+                                    repo[sset[0][0]].rev() == ctx.rev()
+                                   )
+                if nodivergencerisk:
+                    duplicate = False
+                else:
+                    displayer.show(ctx)
+                    index = ui.promptchoice(
+                        _("reviving this changeset will create divergence"
+                        " unless you make a duplicate.\n(a)llow divergence or"
+                        " (d)uplicate the changeset? $$ &Allowdivergence $$ "
+                        "&Duplicate"), 0)
+                    choice = ['allowdivergence', 'duplicate'][index]
+                    if choice == 'allowdivergence':
+                        duplicate = False
+                    else:
+                        duplicate = True
+
             new, unusedvariable = rewrite(repo, ctx, [], ctx,
                                           [p1, p2],
                                           commitopts={'extra': extra})
             # store touched version to help potential children
             newmapping[ctx.node()] = new
+
             if not duplicate:
                 obsolete.createmarkers(repo, [(ctx, (repo[new],))])
             phases.retractboundary(repo, tr, ctx.phase(), [new])
diff --git a/tests/test-touch.t b/tests/test-touch.t
--- a/tests/test-touch.t
+++ b/tests/test-touch.t
@@ -41,6 +41,9 @@  Revive usage
   @  1:[0-9a-f]{12} a (re)
   
   $ hg touch .
+  [1] a
+  reviving this changeset will create divergence unless you make a duplicate.
+  (a)llow divergence or (d)uplicate the changeset?  a
   2 new divergent changesets
   $ hg log -G
   @  4:[0-9a-f]{12} a (re)
@@ -110,3 +113,15 @@  check move data kept after rebase on tou
   A gna2
     gna1
   R gna1
+
+check that the --duplicate option does not create divergence
+
+  $ hg touch --duplicate 11 --hidden
+  1 new unstable changesets
+
+check that reviving a changeset with no successor does not show the prompt
+
+  $ hg prune 14
+  1 changesets pruned
+  $ hg touch 14 --hidden
+  1 new unstable changesets