README
author Pierre-Yves David <pierre-yves.david@logilab.fr>
Thu, 08 Sep 2011 18:20:01 +0200
changeset 54 ad1a4fb0fc49
parent 48 5fd7b64aa8c5
child 59 02fba620d139
permissions -rw-r--r--
Make states more resilient to missing head In particuliar pushkey is now more robust (with a very naif approach)

=============================
Mutable History For Mercurial
=============================

This repository holds three experimental extensions that introduce concepts
related to history rewriting in mercurial.

:states:

    Introduce a state concept. It allows to track which changesets have been
    made public and immutable and which you want to keep local.

:obsolete:

    Introduce an ``obsolete`` concept that tracks new versions of rewritten
    changesets.

:rewrite:
    A collection of commands to rewrite the mutable part of the history.



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





Obsolete Extension
======================

state: in progress

This extension introduces the *obsolete* concept. It adds a new *obsolete*
relation between two changesets. A relation ``<changeset B> obsolete <changeset
A>`` is set to denote that ``<changeset B>`` is new version of ``<changeset
A>``.

The *obsolete* relation act as a **perpendicular history** to the standard
changeset history. Standard changeset history versions files. The *obsolete*
relation versions changesets.

Usage and Feature
------------------

obsolete changesets are hidden.

Commands
........


a ``debugobsolete`` command has been added.


To Do
-----

* do not exchange them

* handle non-obsolete children

* exchange the obsolete information

* refuse to obsolete published changesets

* handle split

* handle conflict

* handle out of sync

rewrite Extension
======================

state: To be written