diff mercurial/commands.py @ 15830:8ed112ed774a

phases: add a phases command to display and manipulate phases
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Tue, 10 Jan 2012 19:45:35 +0100
parents 2c480532f36e
children 0ecaf1e72609
line wrap: on
line diff
--- 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