Mercurial > hg > mutable-history
changeset 59:02fba620d139
move part of the readme about states in states itself.
author | Pierre-Yves David <pierre-yves.david@logilab.fr> |
---|---|
date | Fri, 09 Sep 2011 15:56:50 +0200 |
parents | 2ba7355f6e11 |
children | 14a4499d2cd6 |
files | README hgext/states.py |
diffstat | 2 files changed, 237 insertions(+), 128 deletions(-) [+] |
line wrap: on
line diff
--- a/README +++ b/README @@ -23,129 +23,7 @@ **These extensions are experimental and are not meant for production.** -States Extension -================ - -state: experimentally functional - -(see http://mercurial.selenic.com/wiki/StatesPlan) - -This extension adds the state concept. A changeset now has one of the following -*states*: - -:published: - - Changesets in the ``published`` state are the core of the history. They are - changesets that you published to the world. People can expect them to always - exist. They are changesets as you know them. **By default all changesets - are published** - - * They are exchanged with other repositories (included in pull//push). - - * They are not mutable, extensions rewriting history should refuse to - rewrite them. - -:ready: - - Changesets in the ``ready`` state have not yet been accepted in the - immutable history. You can share them with others for review, testing or - improvement. Any ``ready`` changeset can either be included in the - published history (and become immutable) or be rewritten and never make it - to the published history. - - * They are exchanged with other repositories (included in pull//push). - * They are mutable, extensions rewriting history accept to work on them. - -:draft: - - Changesets in the ``draft`` state are heavy work in progress you are not - yet willing to share with others. - - * They are not exchanged with other repositories. pull//push do not see them. - * They are mutable, extensions rewriting history accept to work on them. - - -States of changesets have to be consistent with each other. A ``published`` -changeset can only have ``published`` ancestors. A ``ready`` changeset can only -have ``published`` or ``ready`` ancestors. - - -Usage and Feature ------------------- - -By default all changesets in the repository are ``published``. Other states must -be explicitly activated. When a state is not activated, changesets in this state -are handled as changesets of the state before it (``draft`` are handled as -``ready``, ``ready`` are handled as ``published``). - -Changesets will automatically move to ``published`` state when: - -* pushed to a repo that doesn't support the ``ready`` state. - -* Tagged by a non local tag. - -Commands -........ - -The extension adds a ``hg states`` command to choose which states are used by a -repository, see ``hg help states for details``. - -A command is also added for each active state. The command has the name of the -state and is used to manually change the state of a changeset. This is mainly -useful to move changesets from ``draft`` to ``ready``.:: - - hg ready tip - -Template -........ - -A new template keyword ``{state}`` has been added. - -Revset -........ - -We add new ``readyheads()`` and ``publishedheads()`` revset directives. This -returns the heads of each state **as if all of them were activated**. - -FAQ ---- - -Why to you store activate state outside ``.hg/hgrc``? -..................................................... - -``.hg/hgrc`` might be ignored for trust reason. We don't want the trust issue -to interfer with enabled state information. - -Why is the ``dead`` state missing? -..................................................... - -1. The ``dead`` state has a different behaviour that requires more work to be -implemented. - -2. I believe that the use cases of ``dead changeset`` are better covered by the -``obsolete`` extension. - -To Do ------ - -* be robust to unknown changeset in boundary - -* Moving boundary backward (code exists in the ``liquid`` extension done at the - CPH sprint) - -* support for default value in configuration (for init and clone) - -* stronger pull//push support (unknown remote heads confuse the current code) - -* display the number of changesets that change state when activating a state. - -* have a switch to select if changesets do change state on state activation. - -* proper revset directive. - - - for changeset in states - - for "in use" changeset heads. - +See each extension documentation for details
--- a/hgext/states.py +++ b/hgext/states.py @@ -9,13 +9,244 @@ '''introduce the state concept for mercurial changeset -Change can be in the following state: +(see http://mercurial.selenic.com/wiki/StatesPlan) + +General concept +=============== + +This extension adds the state concept. A changeset are now in a specific state +that control they mutability and they exchange. + +States properties +................. + +The states extension currently alter two property for changeset + +:mutability: history rewritten tool should refuse to work on immutable changeset +:sharing: shared changeset are exchanged during pull and push. other are not + +Here is a small summary of the current property of state existing state:: + + || || mutable || shared || + || published || || x || + || ready || x || x || + || draft || x || || + +States consistency and ordering +............................... + +States of changesets have to be consistent with each other. A changeset can only have ancestors of it's state (or a compatible states) + +Example: + + A ``published`` changeset can't have a ``draft`` parent. + +a state is compatible with itself and all "smaller" states. Order is as follow:: + + published < ready < draft + + +.. note: + + This section if probably far too conceptual for people. The result is just + that: A ``published`` changeset can only have ``published`` ancestors. A + ``ready`` changeset can only have ``published`` or ``ready`` ancestors. + + Moreover There is a need for a nice word to refer to "a state smaller than another" + + +States details +============== + + +published + Changesets in the ``published`` state are the core of the history. They are + changesets that you published to the world. People can expect them to always + exist. They are changesets as you know them. **By default all changesets + are published** + + - They are exchanged with other repositories (included in pull//push). + + - They are not mutable, extensions rewriting history should refuse to + rewrite them. + +ready + Changesets in the ``ready`` state have not yet been accepted in the + immutable history. You can share them with others for review, testing or + improvement. Any ``ready`` changeset can either be included in the + published history (and become immutable) or be rewritten and never make it + to the published history. + + - They are exchanged with other repositories (included in pull//push). + + - They are mutable, extensions rewriting history accept to work on them. + +draft + + Changesets in the ``draft`` state are heavy work in progress you are not + yet willing to share with others. + + - They are not exchanged with other repositories. pull//push do not see them. + - They are mutable, extensions rewriting history accept to work on them. + +-- + +.. note: + + The Dead states mentionned in on the wiki page are missing. There is two main reason for it: + + 1. The ``dead`` state has a different behaviour that requires more work to be + implemented. + + 2. I believe that the use cases of ``dead changeset`` are better covered by + the ``obsolete`` extension. + +-- + +.. note: + + I'm tempted to add a state with the same property that ``ready`` for review + workflow.:: + + || || mutable || shared || + || published || || x || + || ready || x || x || + || inprogress|| x || x || + || draft || x || || + + The ``ready`` state would be for changeset that wait review of someone that + can "publish" them. + + + +Current Feature and usage +========================= + + +Enabling states +............... -0 immutable -1 mutable -2 private +The extension adds a :hg:`hg states` command to display and choose which states +are used by a repository, see :hg:`hg states` for details. + +By default all changesets in the repository are ``published``. Other states +must be explicitly activated. Changeset in a remote repository that doesn't +support states are all seen as ``published``. + +.. note: + + When a state is not activated, changesets in this state are handled as + changesets of the previous state it (``draft`` are handled as ``ready``, + ``ready`` are handled as ``published``). + +TODO: + +- have a configuration in hgrc:: + + [states] + ready=(off|on)(-inherit)? + <state>=(off|on)(-inherit)? + + :off: state disabled for new repo + :on: state enabled for new repo + :inherit: if present, inherit states of source on :hg:`clone`. + +- have a switch to select if changesets do change state on state activation. + +- display the number of changesets that change state when activating a state. + + + +State transition +................ + +Changeset you create locally will be in the ``draft`` state. (or any previous +state if draft isn't enabled) + +There is some situation where the state of a changeset will change +automatically. Automatic movement always go in the same direction.: ``draft -> +``ready`` -> ``published`` + +1. When you pull or push boundary move. Common changeset that are ``published`` in +one of the two repository are set to ``published``. Same goes for ``ready`` etc +(states are evaluated from in increasing order XXX I bet no one understand this +parenthesis. Pull operation alter the local repository. push alter both local +and remote repository. + +.. note: + + As Repository without any specific state have all their changeset + ``published``, Pushing to such repo will ``publish`` all common changeset. + +2. Tagged changeset get automatically Published. The tagging changeset is +tagged too... This doesn't apply to local tag. + + +You can also manually change changeset state with a dedicated command for each +state. See :hg:`published`, :hg:`ready` and :hg:`draft` for details. + +XXX maybe we can details the general behaviour here -name are not fixed yet. +:hg <state> revs: move boundary of state so it includes revs + ( revs included in ::<state>heads()) +:hg --exact <state> revs: move boundary so that revs are exactly in state + <state> ( all([rev.state == <state> for rev in + revs])) +:hg --exact --force <state> revs: move boundary event if it create inconsistency + (with tag for example) + +TODO: + +- implement --exact + +- implement consistency check + +- implement --force + + +Existing command change +....................... + +As said in the previous section: + +:commit: Create draft changeset (or the first enabled previous changeset). +:tag: Move tagged and tagging changeset in the ``published`` state. +:incoming: Exclude ``draft`` changeset of remote repository. +:outgoing: Exclude ``draft`` changeset of local repository. +:pull: As :hg:`in` + change state of local changeset according to remote side. +:push: As :hg:`out` + sync state of common changeset on both side + +Template +........ + +A new template keyword ``{state}`` has been added. + +Revset +...... + + We add new ``readyheads()`` and ``publishedheads()`` revset directives. This + returns the heads of each state **as if all of them were activated**. + + XXX TODO - I would like to + + - move the current ``<state>heads()`` directives to + _``<state>heads()`` + + - add ``<state>heads()`` directives to that return the currently in used heads + + - add ``<state>()`` directives that + +implementation +========================= + +To be completed + +Why to you store activate state outside ``.hg/hgrc``? : + + ``.hg/hgrc`` might be ignored for trust reason. We don't want the trust + issue to interfer with enabled state information. + + ''' import os from functools import partial