phases: add a phases command to display and manipulate phases
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Tue, 10 Jan 2012 19:45:35 +0100
changeset 15830 8ed112ed774a
parent 15829 2c480532f36e
child 15831 0ecaf1e72609
phases: add a phases command to display and manipulate phases
mercurial/commands.py
tests/test-alias.t
tests/test-commandserver.py.out
tests/test-debugcomplete.t
tests/test-globalopts.t
tests/test-help.t
tests/test-phases.t
tests/test-strict.t
--- a/mercurial/commands.py	Tue Jan 10 10:18:19 2012 +0200
+++ b/mercurial/commands.py	Tue Jan 10 19:45:35 2012 +0100
@@ -18,6 +18,7 @@
 import minirst, revset, fileset
 import dagparser, context, simplemerge
 import random, setdiscovery, treediscovery, dagutil
+import phases as phasesmod
 
 table = {}
 
@@ -4214,6 +4215,58 @@
             else:
                 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
 
+@command('^phase',
+    [('p', 'public', False, _('Set changeset to public')),
+     ('d', 'draft', False, _('Set changeset to draft')),
+     ('s', 'secret', False, _('Set changeset to secret')),
+     ('f', 'force', False, _('allow to move boundary backward')),
+     ('r', 'rev', [], _('target revision')),
+    ],
+    _('[-p|-d|-s] [-f] [-C] [-r] REV'))
+def phase(ui, repo, *revs, **opts):
+    """set or show the current phase name
+
+    With no argument, show the phase name of specified revisions.
+
+    With on one of `--public`, `--draft` or `--secret`, change the phase value.
+
+    Unless -f/--force is specified, :hg:`phase` won't move changeset from a
+    lower phase to an higher phase. Phase are ordered as follow:
+
+        public < draft < secret.
+    """
+    # search for a unique phase argument
+    targetphase = None
+    for idx, name in enumerate(phasesmod.phasenames):
+        if opts[name]:
+            if targetphase is not None:
+                raise util.Abort('only one phase can be specified')
+            targetphase = idx
+
+    # look for specified revision
+    revs = list(revs)
+    revs.extend(opts['rev'])
+    if not revs:
+        raise NotImplementedError('working directory phase not implemented '
+                                  'yet')
+    lock = None
+    if targetphase is None:
+        # display
+        for ctx in repo.set('%lr', revs):
+            ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
+    else:
+        lock = repo.lock()
+        try:
+            # set phase
+            nodes = [ctx.node() for ctx in repo.set('%lr', revs)]
+            if not nodes:
+                raise util.Abort(_('empty revision set'))
+            phasesmod.advanceboundary(repo, targetphase, nodes)
+            if opts['force']:
+                phasesmod.retractboundary(repo, targetphase, nodes)
+        finally:
+            lock.release()
+
 def postincoming(ui, repo, modheads, optupdate, checkout):
     if modheads == 0:
         return
--- a/tests/test-alias.t	Tue Jan 10 10:18:19 2012 +0200
+++ b/tests/test-alias.t	Tue Jan 10 19:45:35 2012 +0100
@@ -334,6 +334,7 @@
    init       create a new repository in the given directory
    log        show revision history of entire repository or files
    merge      merge working directory with another revision
+   phase      set or show the current phase name
    pull       pull changes from the specified source
    push       push changes to the specified destination
    remove     remove the specified files on the next commit
@@ -360,6 +361,7 @@
    init       create a new repository in the given directory
    log        show revision history of entire repository or files
    merge      merge working directory with another revision
+   phase      set or show the current phase name
    pull       pull changes from the specified source
    push       push changes to the specified destination
    remove     remove the specified files on the next commit
@@ -386,6 +388,7 @@
    init       create a new repository in the given directory
    log        show revision history of entire repository or files
    merge      merge working directory with another revision
+   phase      set or show the current phase name
    pull       pull changes from the specified source
    push       push changes to the specified destination
    remove     remove the specified files on the next commit
--- a/tests/test-commandserver.py.out	Tue Jan 10 10:18:19 2012 +0200
+++ b/tests/test-commandserver.py.out	Tue Jan 10 19:45:35 2012 +0100
@@ -26,6 +26,7 @@
  init       create a new repository in the given directory
  log        show revision history of entire repository or files
  merge      merge working directory with another revision
+ phase      set or show the current phase name
  pull       pull changes from the specified source
  push       push changes to the specified destination
  remove     remove the specified files on the next commit
--- a/tests/test-debugcomplete.t	Tue Jan 10 10:18:19 2012 +0200
+++ b/tests/test-debugcomplete.t	Tue Jan 10 19:45:35 2012 +0100
@@ -32,6 +32,7 @@
   outgoing
   parents
   paths
+  phase
   pull
   push
   recover
@@ -198,6 +199,7 @@
   init: ssh, remotecmd, insecure
   log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, hidden, patch, git, limit, no-merges, stat, style, template, include, exclude
   merge: force, rev, preview, tool
+  phase: public, draft, secret, force, rev
   pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
   push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
   remove: after, force, include, exclude
--- a/tests/test-globalopts.t	Tue Jan 10 10:18:19 2012 +0200
+++ b/tests/test-globalopts.t	Tue Jan 10 19:45:35 2012 +0100
@@ -311,6 +311,7 @@
    outgoing     show changesets not found in the destination
    parents      show the parents of the working directory or revision
    paths        show aliases for remote repositories
+   phase        set or show the current phase name
    pull         pull changes from the specified source
    push         push changes to the specified destination
    recover      roll back an interrupted transaction
@@ -393,6 +394,7 @@
    outgoing     show changesets not found in the destination
    parents      show the parents of the working directory or revision
    paths        show aliases for remote repositories
+   phase        set or show the current phase name
    pull         pull changes from the specified source
    push         push changes to the specified destination
    recover      roll back an interrupted transaction
--- a/tests/test-help.t	Tue Jan 10 10:18:19 2012 +0200
+++ b/tests/test-help.t	Tue Jan 10 19:45:35 2012 +0100
@@ -15,6 +15,7 @@
    init       create a new repository in the given directory
    log        show revision history of entire repository or files
    merge      merge working directory with another revision
+   phase      set or show the current phase name
    pull       pull changes from the specified source
    push       push changes to the specified destination
    remove     remove the specified files on the next commit
@@ -36,6 +37,7 @@
    init       create a new repository in the given directory
    log        show revision history of entire repository or files
    merge      merge working directory with another revision
+   phase      set or show the current phase name
    pull       pull changes from the specified source
    push       push changes to the specified destination
    remove     remove the specified files on the next commit
@@ -81,6 +83,7 @@
    outgoing     show changesets not found in the destination
    parents      show the parents of the working directory or revision
    paths        show aliases for remote repositories
+   phase        set or show the current phase name
    pull         pull changes from the specified source
    push         push changes to the specified destination
    recover      roll back an interrupted transaction
@@ -157,6 +160,7 @@
    outgoing     show changesets not found in the destination
    parents      show the parents of the working directory or revision
    paths        show aliases for remote repositories
+   phase        set or show the current phase name
    pull         pull changes from the specified source
    push         push changes to the specified destination
    recover      roll back an interrupted transaction
@@ -225,6 +229,8 @@
         show revision history of entire repository or files
    merge:
         merge working directory with another revision
+   phase:
+        set or show the current phase name
    pull:
         pull changes from the specified source
    push:
@@ -541,6 +547,7 @@
    init       create a new repository in the given directory
    log        show revision history of entire repository or files
    merge      merge working directory with another revision
+   phase      set or show the current phase name
    pull       pull changes from the specified source
    push       push changes to the specified destination
    remove     remove the specified files on the next commit
@@ -568,6 +575,7 @@
    init       create a new repository in the given directory
    log        show revision history of entire repository or files
    merge      merge working directory with another revision
+   phase      set or show the current phase name
    pull       pull changes from the specified source
    push       push changes to the specified destination
    remove     remove the specified files on the next commit
@@ -643,6 +651,7 @@
    outgoing     show changesets not found in the destination
    parents      show the parents of the working directory or revision
    paths        show aliases for remote repositories
+   phase        set or show the current phase name
    pull         pull changes from the specified source
    push         push changes to the specified destination
    recover      roll back an interrupted transaction
--- a/tests/test-phases.t	Tue Jan 10 10:18:19 2012 +0200
+++ b/tests/test-phases.t	Tue Jan 10 19:45:35 2012 +0100
@@ -26,7 +26,7 @@
 
 Draft commit are properly created over public one:
 
-  $ hg pull -q . # XXX use the dedicated phase command once available
+  $ hg phase --public .
   $ hglog
   1 0 B
   0 0 A
@@ -154,3 +154,109 @@
   4 2 E
   5 2 H
   7 2 merge B' and E
+
+Test phase command
+===================
+
+initial picture
+
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ hg log -G --template "{rev} {phase} {desc}\n"
+  @    7 secret merge B' and E
+  |\
+  | o  6 draft B'
+  | |
+  +---o  5 secret H
+  | |
+  o |  4 secret E
+  | |
+  o |  3 draft D
+  | |
+  o |  2 draft C
+  |/
+  o  1 public B
+  |
+  o  0 public A
+  
+
+display changesets phase
+
+(mixing -r and plain rev specification)
+
+  $ hg phase 1::4 -r 7
+  1: public
+  2: draft
+  3: draft
+  4: secret
+  7: secret
+
+
+move changeset forward
+
+(with -r option)
+
+  $ hg phase --public -r 2
+  $ hg log -G --template "{rev} {phase} {desc}\n"
+  @    7 secret merge B' and E
+  |\
+  | o  6 draft B'
+  | |
+  +---o  5 secret H
+  | |
+  o |  4 secret E
+  | |
+  o |  3 draft D
+  | |
+  o |  2 public C
+  |/
+  o  1 public B
+  |
+  o  0 public A
+  
+
+move changeset backward
+
+(without -r option)
+
+  $ hg phase --draft --force 2
+  $ hg log -G --template "{rev} {phase} {desc}\n"
+  @    7 secret merge B' and E
+  |\
+  | o  6 draft B'
+  | |
+  +---o  5 secret H
+  | |
+  o |  4 secret E
+  | |
+  o |  3 draft D
+  | |
+  o |  2 draft C
+  |/
+  o  1 public B
+  |
+  o  0 public A
+  
+
+move changeset forward and backward
+
+  $ hg phase --draft --force 1::4
+  $ hg log -G --template "{rev} {phase} {desc}\n"
+  @    7 secret merge B' and E
+  |\
+  | o  6 draft B'
+  | |
+  +---o  5 secret H
+  | |
+  o |  4 draft E
+  | |
+  o |  3 draft D
+  | |
+  o |  2 draft C
+  |/
+  o  1 draft B
+  |
+  o  0 public A
+  
--- a/tests/test-strict.t	Tue Jan 10 10:18:19 2012 +0200
+++ b/tests/test-strict.t	Tue Jan 10 19:45:35 2012 +0100
@@ -26,6 +26,7 @@
    init       create a new repository in the given directory
    log        show revision history of entire repository or files
    merge      merge working directory with another revision
+   phase      set or show the current phase name
    pull       pull changes from the specified source
    push       push changes to the specified destination
    remove     remove the specified files on the next commit