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

Jesper Schmidt schmiidt at gmail.com
Tue Dec 27 16:59:09 CST 2011


On Tue, 27 Dec 2011 00:11:12 +0100, Pierre-Yves David  
<pierre-yves.david at ens-lyon.org> wrote:

>
> 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)
>

Too bad, because I prefer 'private' over 'secret'. When I hear secret,
I cannot help thinking about security levels, which is not very helpful
in this context. Private, on the other hand, leads me in the right
direction as being the opposite of public.

> 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
>

Have you considered using a verb instead of a noun? Nouns are normally used
to show stuff while verbs indicate that the command changes some state.

What about using 'hg promote' to manually promoting a changeset to a higher
phase and 'hg demote' to manually demoting it to a lower phase. I like the
fact that you need to express your intention (promoting or demoting)
explicitly, when you are assigning phases manually.

> 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.
>
>


-- 
Jesper


More information about the Mercurial-devel mailing list