RFC: Phase UI (revset, phase command and others)

Pierre-Yves David pierre-yves.david at ens-lyon.org
Mon Dec 26 17:11:12 CST 2011


This email talks about phase and assumes reader are familiar with this new
concept.  You can find more informations about this new concept in the wiki
page, previous discussion and module documentation related to phase.

wikipage: http://mercurial.selenic.com/wiki/StatesPlan
module:   http://selenic.com/hg/file/3bcfea777efc/mercurial/phases.py

This email aims to sum up the current decision about phases impact on the ui
and to suggest solutions for area yet undecided.


Phase name
============

The current naming scheme is:

           immutable shared
   public:     X        X
   draft:               X
   secret:

The two rules leading to such scheme are:

1) Thou shalt not pick phases name whose initial clash with each other.
   (eg: no Public/Private)

2) Thou shalt not pick phases whose initial clash with '--force' or '--rev'.
   (eg: no frozen )

Multiple people express enthusiasm for using "private" instead of "secret". I
prefer "private" too but we need a valid replacement for "public" to avoid
initial clash. Anyone with an idea brilliant enough to convince Matt should
speak quickly.


Phase Appearance In UI
======================

Data related to phase will appear in several places:

Changesets Log
-----------------

hg log output will include phase name for changeset not in the public phase.

   changeset:   15781:2ebe3d0ce91d
   branch:      stable
   user:        FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
   date:        Fri Dec 16 21:09:41 2011 +0900
   summary:     i18n: use encoding.lower/upper for encoding aware case folding
   phase:       draft

This also applies to other commands with similar output

On the template side, {phase} and {phasestr}  keyword can be used to display
phase number and phase name of a changeset.

Phase Movement
--------------

The user will be informed of phase movement the same way changegroup addition
are notified (check last line):

   % 22:31 marmoute at yamac ~/src/pylint > hg pushing
   real URL is http://hg.logilab.org/pylint
   pushing to http://hg.logilab.org/pylint
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 60 changesets with 173 changes to 314 files
   90 changesets changed phases

more verbose output may provide additional information:

   90 changesets changed phases
   73 changesets moved to public phase
   17 changesets moved to draft phase

This applies to any command changing the phase of changesets.

Extension
-----------

Extensions rewriting history will refuse to work on immutable changeset:

   abort: Can't rebase immutable changeset e1c4361dd923
   (see hg help phases for details)

Impacted core extensions are: mq and rebase

revset
-------

revset to select changeset according to their phase will be implemented.

The naive solution is:

   public()     match changeset in public phase.
   draft()      match changeset in draft phase.
   secret()     match changeset in secret phase.

But in practice we want to be able to do more complicated queries:

   * "Match all changeset at least draft" --> (draft() + secret())
   * "Match all changeset at most draft" --> (draft() + public())

There are multiple options to achieve this.

Solution A: add more revset symbols
```````````````````````````````````````````````````

Adding "exchanged()" and "mutable()" should do it.

pro:
  * simple to use
con:
  * multiplies symbols
  * Does not scale well if we add phases

Solution B: add argument to revset
``````````````````````````````````````````````````

We add an "operator" argument to revset to control how it should be
interpreted:

   Match any changeset in phase draft or lower --> "draft('<=')"

Possible values are '<', '<=', '='(default), '>=', '>'.

pro:
   * keep simple usage simple
   * cover most things people will want to express (except phase between X and Y)
cons:
   * complicated usecase are a bit more complicated


Solution C: Use a single symbol
``````````````````````````````````````````````````

We can use a single "phases" revset taking a "phase-set" in argument:

   match changesets in draft phase --> phase('draft)
   match changesets in draft phase or lower --> phase('<=draft)
   match changeset between public and secret phase -->  phase('public::draft')

pro:
   * Add less symbol
   * everything is done using the same symbol
   * complex case are simpler to express
   * cover any complicated case people might want
cons:
   * Make simple case more verbose


Automatic phase movement
========================

Push/Pull:

   Pull and push Synchronize phase with remote side

   Pushing to publishing server makes changesets public

mq:

   changeset handled by mq are secret.

   qnew and qpush create secret changeset

   qimport moves changeset into secret phase

   qfinish moves changeset into draft phase if they do not have secret parent
   (small chance of error here)

Tag:

   Current history rewriting extension does not handle tag.

   As suggested by Matt during 1.9 sprint, hg tag should make changeset public.

Rollback:

   Restore phase to they state prior last revlog transaction (as for bookmark)



Phase command
=============

Phase of changeset can be manually altered with the "hg phases" command

hg phases [-C|-p|-d|-s] [-b|-e] [revset]

set or show phase of changeset

If no revset is provided, it applies to the current working directory phase.

options:

-p --public   Set target into public phase
-d --draft    Set target into draft phase (or leave it in lower phase (public))
-s --secret   Set target into secret phase (or leave it in lower phase (draft
              and public))


-b --backward reverse the logic, phase are left in upper phase, not lower
-e --exact    all target changeset are exactly set in the specified phase

-C --clear    reset next commit phase to default (max of parent phase and
              phases.new-commit option)


Exact help text is to be tuned to remove the confusing lower//upper phase stuff.


-- 
Pierre-Yves


More information about the Mercurial-devel mailing list