[PATCH 08 of 18] add function to move phase boundaries forward

pierre-yves.david at logilab.fr pierre-yves.david at logilab.fr
Mon Oct 10 07:28:04 CDT 2011


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1318239338 -7200
# Node ID bd503fc2b326ed044990f798f940fbb09aabc862
# Parent  3f1cd2b3ac07d28ca5a734add488808b665c76a6
add function to move phase boundaries forward

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -7,11 +7,11 @@
 
 from node import hex, bin, nullid, nullrev, short
 from lock import release
 from i18n import _, gettext
 import os, re, difflib, time, tempfile, errno
-import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
+import hg, scmutil, util, revlog, extensions, copies, error, bookmarks, phases
 import patch, help, url, encoding, templatekw, discovery
 import archival, changegroup, cmdutil, hbisect
 import sshserver, hgweb, hgweb.server, commandserver
 import merge as mergemod
 import minirst, revset, fileset
@@ -3965,10 +3965,38 @@ def postincoming(ui, repo, modheads, opt
         else:
             ui.status(_("(run 'hg heads' to see heads)\n"))
     else:
         ui.status(_("(run 'hg update' to get a working copy)\n"))
 
+ at command('^phase', 
+    [('p', 'phase', '', _('change phase of the specified revision or range'), _('PHASE')),
+     ('r', 'rev', '', _('a revision or range for which to change the phase'), _('REV')),
+    ],
+    _('[-p PHASE] [[-r] REV]'))
+
+def phase(ui, repo, *changesets, **opts):
+    """
+    Manage the phase of changesets.
+    """
+    phase = opts.get('phase')
+    if not phase:
+        raise util.Abort(_('no phase specifed'),
+                         hint=_('use --phase option with one of: %r' % phases.allphases))
+    if not phase.isdigit() or int(phase) not in phases.allphases:
+        raise util.Abort(_('unknown phase: %s' % phase),
+                         hint=_('use one of: %r' % phases.allphases))
+    phase = int(phase)
+    changesets += tuple(opts.get('rev', []))
+    if not changesets:
+        raise util.Abort(_("phase requires at least one changeset"))
+    revs = scmutil.revrange(repo, changesets)
+    if phases.asboundary(repo, phase, map(repo.changelog.node, revs)):
+        phases.writeheads(repo)
+
+    return 0
+
+
 @command('^pull',
     [('u', 'update', None,
      _('update to new branch head if changesets were pulled')),
     ('f', 'force', None, _('run even when remote repository is unrelated')),
     ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -98,5 +98,26 @@ def invalidatecache(repo):
     """Invalidate phase cache"""
     if os.path.exists(repo.join('cache/phases')):
         util.unlink(repo.join('cache/phases'))
     if '_phasesrev' in vars(repo):
         del repo._phasesrev # clear property cache
+
+
+### Moving
+##########
+
+def asboundary(repo, phase, nodes):
+    """Add nodes to a phase boundary"""
+    if phase not in trackedphases:
+        return False
+    heads = repo._phasesheads[phase]
+    olds = heads.copy()
+    heads.update(set(nodes))
+    if olds != heads:
+        if nullid in heads:
+            heads.remove(nullid)
+        revs = map(repo.changelog.rev, heads)
+        ctxs = repo.set('heads(::(%ld))', revs)
+        nodes = set([ctx.node() for ctx in ctxs])
+        heads.intersection_update(nodes) 
+    asboundary(repo, phase + 1, nodes) # cascading
+    return olds != heads
diff --git a/tests/test-phases.t b/tests/test-phases.t
--- a/tests/test-phases.t
+++ b/tests/test-phases.t
@@ -1,10 +1,65 @@
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "$1"
+  > }
   $ alias hglog='hg log --template "{rev} {phase} {desc}\n"'
 
   $ hg init initialrepo
   $ cd initialrepo
-  $ touch sam
-  $ hg add sam
-  $ hg ci -m 'first'
+  $ mkcommit A
+  $ mkcommit B
+  $ mkcommit C
+  $ mkcommit D
+  $ mkcommit E
 
   $ hglog
-  0 1 first
+  4 1 E
+  3 1 D
+  2 1 C
+  1 1 B
+  0 1 A
+
+check wrong argument
+--------------------
+  $ hg phase -r1
+  abort: no phase specifed
+  (use --phase option with one of: [0, 1])
+  [255]
+
+  $ hg phase -p alain -r1
+  abort: unknown phase: alain
+  (use one of: [0, 1])
+  [255]
+
+  $ hg phase -p1
+  abort: phase requires at least one changeset
+  [255]
+
+Simpliest test: change the phase of the last changeset
+------------------------------------------------------
+  $ hg phase -p 0 -r 0
+  $ hglog
+  4 1 E
+  3 1 D
+  2 1 C
+  1 1 B
+  0 0 A
+ 
+  $ hg phase -p 0 -r 2
+  $ hglog
+  4 1 E
+  3 1 D
+  2 0 C
+  1 0 B
+  0 0 A
+ 
+  $ hg phase -p 0 -r 4
+  $ hglog
+  4 0 E
+  3 0 D
+  2 0 C
+  1 0 B
+  0 0 A
+
+


More information about the Mercurial-devel mailing list