--- a/mercurial/phases.py Thu Dec 15 15:27:11 2011 -0600
+++ b/mercurial/phases.py Thu Dec 15 23:08:09 2011 +0100
@@ -1,11 +1,99 @@
-# Mercurial phases support code
-#
-# Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
-# Logilab SA <contact@logilab.fr>
-# Augie Fackler <durin42@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
+""" Mercurial phases support code
+
+ ---
+
+ Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+ Logilab SA <contact@logilab.fr>
+ Augie Fackler <durin42@gmail.com>
+
+ This software may be used and distributed according to the terms of the
+ GNU General Public License version 2 or any later version.
+
+ ---
+
+This module implements most phase logic in mercurial.
+
+
+Basic Concept
+=============
+
+A 'changeset phases' is an indicator that tells us how a changeset is
+manipulated and communicated. The details of each phase is described below,
+here we describe the properties they have in common.
+
+Like bookmarks, phases are not stored in history and thus are not permanent and
+leave no audit trail.
+
+First, no changeset can be in two phases at once. Phases are ordered, so they
+can be considered from lowest to highest. The default, lowest phase is 'public'
+- this is the normal phase of existing changesets. A child changeset can not be
+in a lower phase than its parents.
+
+These phases share a hierarchy of traits:
+
+ immutable shared
+ public: X X
+ draft: X
+
+local commits are draft by default
+
+Phase movement and exchange
+============================
+
+Phase data are exchanged by pushkey on pull and push. Some server have a
+publish option set, we call them publishing server. Pushing to such server make
+draft changeset publish.
+
+A small list of fact/rules define the exchange of phase:
+
+* old client never changes server states
+* pull never changes server states
+* publish and old server csets are seen as public by client
+
+
+Here is the final table summing up the 49 possible usecase of phase exchange:
+
+ server
+ old publish non-publish
+ N X N D P N D P
+ old client
+ pull
+ N - X/X - X/D X/P - X/D X/P
+ X - X/X - X/D X/P - X/D X/P
+ push
+ X X/X X/X X/P X/P X/P X/D X/D X/P
+ new client
+ pull
+ N - P/X - P/D P/P - D/D P/P
+ D - P/X - P/D P/P - D/D P/P
+ P - P/X - P/D P/P - P/D P/P
+ push
+ D P/X P/X P/P P/P P/P D/D D/D P/P
+ P P/X P/X P/P P/P P/P P/P P/P P/P
+
+Legend:
+
+ A/B = final state on client / state on server
+
+ * N = new/not present,
+ * P = public,
+ * D = draft,
+ * X = not tracked (ie: the old client or server has no internal way of
+ recording the phase.)
+
+ passive = only pushes
+
+
+ A cell here can be read like this:
+
+ "When a new client pushes a draft changeset (D) to a publishing server
+ where it's not present (N), it's marked public on both sides (P/P)."
+
+Note: old client behave as publish server with Draft only content
+- other people see it as public
+- content is pushed as draft
+
+"""
import errno
from node import nullid, bin, hex, short