Differences between revisions 19 and 20
Revision 19 as of 2012-01-23 16:47:00
Size: 7644
Comment:
Revision 20 as of 2012-01-23 16:48:27
Size: 7668
Comment:
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:


Line 9: Line 6:
The phase concept improves safety of history rewriting and control over changesets exchanged ([[#Available_Phases|read more]]). This phase concept aims to "just works" in a transparent manner for any user ([[#Phase_Movements|read more]]). It is part of Core and always enabled in any new client but doesn't prevent older client to work on a repository ([[#Upgrade_Notes|read more]]). Advanced user may decides to handle phase manually ([[#Publishing_Repository|read more]]).
Line 10: Line 8:
The phase concept improves safety of history rewriting and control over
changesets exchanged ([[#Available_Phases|read more]]). This phase concept aims
to "just works" in a transparent manner for any user ([[#Phase_Movements|read more]]).
It is part of Core and always enabled in any new client but doesn't
prevent older client to work on a repository ([[#Upgrade_Notes|read more]]).
Advanced user may decides to handle phase manually ([[#Publishing Repository|read more]]).

Like bookmarks, phases are not stored in history and thus are not permanent and
leave no audit trail.
Like bookmarks, phases are not stored in history and thus are not permanent and leave no audit trail.
Line 23: Line 13:
Line 30: Line 19:
|| ||immutable ||shared ||
||public ||x ||x ||
||draft || ||x ||
||secret || || ||
Line 31: Line 24:
|| ||immutable ||shared ||
||public || x|| x||
||draft || || x||
||secret || || ||
Line 38: Line 28:
  always exists in your history and are said ''immutable''. History rewriting
 
extension will refuse to delete such '''immutable''' changeset. Every
 
changeset your push or pull from a public server are set in this phase.

 .
always exists in your history and are said ''immutable''. History rewriting extension will refuse to delete such '''immutable''' changeset. Every changeset your push or pull from a public server are set in this phase.
Line 43: Line 32:
  the permanent history. You can safely rewrite them. New commit are draft by
 
default.

. the permanent history. You can safely rewrite them. New commit are draft by default.
Line 47: Line 36:
  other repository. Secret changeset are hidden to remote peer and won't be
  included in push operation. Manual operation or Extension may turn changeset
  secret.
Line 51: Line 37:
Phases split the history in coherent set of changeset. Every changeset in a
phase have ancestor in a phase ''compatible'' with its phase. ''Compatible''
means an changeset ancestors have at least the same traits that the children
changeset. eg: A ''shared'' changeset alway have ''shared'' ancestor and an
''immutable'' changeset always have ''immutable'' ancestors.
 . other repository. Secret changeset are hidden to remote peer and won't be included in push operation. Manual operation or Extension may turn changeset secret.
Line 57: Line 39:
In other word the phase of a changeset is alway equal of higher that the phase
of it's descendant. According to the following order:
Phases split the history in coherent set of changeset. Every changeset in a phase have ancestor in a phase ''compatible'' with its phase. ''Compatible'' means an changeset ancestors have at least the same traits that the children changeset. eg: A ''shared'' changeset alway have ''shared'' ancestor and an ''immutable'' changeset always have ''immutable'' ancestors.
Line 60: Line 41:
    public < draft < secret In other word the phase of a changeset is alway equal of higher that the phase of it's descendant. According to the following order:
Line 62: Line 43:
 . public < draft < secret
Line 63: Line 45:
A changeset is not expected to automatically move from a lower phase to an
higher phase (eg: from ''public'' to draft'') but automatic
A changeset is not expected to automatically move from a lower phase to an higher phase (eg: from ''public'' to draft'') but automatic ''
Line 68: Line 48:
''Phase movement are automatic and transparent and most user don't have to care much about them. The base rule is very simple: ''
Line 69: Line 50:
Phase movement are automatic and transparent and most user don't have to care
much about them. The base rule is very simple:
 . ''“''Any changesets on a remote repository is seen a public''” ''
Line 72: Line 52:
   “''Any changesets on a remote repository is seen a public''” ''One standard exchange commands, the phase of changesets on both side are compared. If differ the lowest phase is choosed. (eg: a changeset known as ''draft'' locally but '''public''' remotely is set public localy. Because public < draft) ''
Line 74: Line 54:
One standard exchange commands, the phase of changesets on both side are
compared. If differ the lowest phase is choosed. (eg: a changeset known as
''draft'' locally but '''public''' remotely is set public localy. Because public
< draft)
''This update happen during standard exchange commands: ''
Line 79: Line 56:
This update happen during standard exchange commands: ''* '''pull''': remote phase data are used to update the phase data on ''
Line 81: Line 58:
* '''pull''': remote phase data are used to update the phase data on
  
the local repo. As pull is read only, it does not change changeset's phase on
 
the remote
 . ''the local repo. As pull is read only, it does not change changeset's phase on the remote ''
Line 85: Line 60:
* '''push''': remote phase data are used to the phase data on the local repo and
 then local phase data are pushed to the local repo.
''* '''push''': remote phase data are used to the phase data on the local repo and ''
Line 88: Line 62:
The real behavior is a it's a bit more complicated than '' changesets on a
remote repository is seen a public'', but this is true for repository keeping
default . If you need a finer behavior, consult the
''[[#Publishing_Repository|publishing repository]]'' section.
 . ''then local phase data are pushed to the local repo. ''
Line 93: Line 64:
New changeset committed locally are ''draft'', but some extension like ''mq''
may create ''secret'' and handle the move from ''secret'' to ''draft''
automatically
''The real behavior is a it's a bit more complicated than '' changesets on a remote repository is seen a public'', but this is true for repository keeping default . If you need a finer behavior, consult the ''[[#Publishing_Repository|publishing repository]]'' section. ''
Line 97: Line 66:
Consult the [[#upgrade_Notes||upgrade Notes]] section to check how phase will
move the first time a new version of Mercurial touch and existing repository.
''New changeset committed locally are ''draft'', but some extension like ''mq'' may create ''secret'' and handle the move from ''secret'' to ''draft'' automatically ''
Line 100: Line 68:
''Consult the [[#upgrade_Notes]] section to check how phase will move the first time a new version of Mercurial touch and existing repository. ''
Line 102: Line 71:

Line 105: Line 72:

Line 108: Line 73:

Line 111: Line 74:

By default any changeset exchanged over the wire are set public. Advanced user
may want a finer behavior. The Publishing repository concept is designed for
this purpose.
''By default any changeset exchanged over the wire are set public. Advanced user may want a finer behavior. The Publishing repository concept is designed for this purpose. ''
Line 117: Line 77:
''Setting a repository as "publishing" alter its behavior **when used as a server**: all changesets are **seen** as public changesets by clients. ''
Line 118: Line 79:
Setting a repository as "publishing" alter its behavior **when used as a
server**: all changesets are **seen** as public changesets by clients.
''So, pushing to a "publishing" repository is the most common way to make changesets public: pushed changesets are seen as public on the remote side and marked as such on local side. ''
Line 121: Line 81:
So, pushing to a "publishing" repository is the most common way to make
changesets public: pushed changesets are seen as public on the remote side and
marked as such on local side.

Note: the "publishing" property have no effects for local operations.
''Note: the "publishing" property have no effects for local operations. ''
Line 128: Line 84:
''Phase is the first step of a series of features aiming at handling mutable history within mercurial. Old client do not support such feature and are unable to hold phase data. The safest solution is to consider as public any changeset going through an old client. ''
Line 129: Line 86:
Phase is the first step of a series of features aiming at handling mutable
history within mercurial. Old client do not support such feature and are unable
to hold phase data. The safest solution is to consider as public any changeset
going through an old client.

Moreover, most hosting solution will not support phase from the beginning.
Having old clients seen as public repositories will not change their usage:
public repositories where you push *immutable* public changesets *shared* with
others.
''Moreover, most hosting solution will not support phase from the beginning. Having old clients seen as public repositories will not change their usage: public repositories where you push *immutable* public changesets *shared* with others. ''
Line 140: Line 89:
''We discussed above that any changeset from a non-phase aware repository should be seen as public. This means that in the following scenario, X is pulled as public:: ''
Line 141: Line 91:
We discussed above that any changeset from a non-phase aware repository should
be seen as public. This means that in the following scenario, X is pulled as
public::
 . {{{
~/A$ old-hg init
~/A$ echo 'babar' > jungle
}}}
 {{{
}}}
 {{{
~/A$ old-hg commit -mA 'X'
}}}
 {{{
~/A$ cd ../B
}}}
 {{{
~/B$ new-hg pull ../A # let's pretend A is served by old-hg
}}}
 {{{
~/B$ new-hg log -r tip
}}}
  . {{{
summary: X phase: public
}}}
Line 145: Line 113:
  ~/A$ old-hg init
  ~/A$ echo 'babar' > jungle
  ~/A$ old-hg commit -mA 'X'
  ~/A$ cd ../B
  ~/B$ new-hg pull ../A # let's pretend A is served by old-hg
  ~/B$ new-hg log -r tip
     summary: X
     phase: public
''We want to keep this behavior while creating/serving the A repository with new-hg. Although committing with any new-hg creates a draft changeset. To stay backward compatible, the pull must see the new commit as public. Non-publishing server will advertise them as draft. Having publishing repository the default is thus necessary to ensure this backward compatibility. ''
Line 154: Line 115:
We want to keep this behavior while creating/serving the A repository with
new-hg. Although committing with any new-hg creates a draft changeset.
To stay backward compatible, the pull must see the new commit as public.
Non-publishing server will advertise them as draft. Having publishing repository
the default is thus necessary to ensure this backward compatibility.

This default value can also be expressed with the following sentence: "By
default, without any configuration, everything you exchange with the outside is
immutable.". This behaviour seems sane.
''This default value can also be expressed with the following sentence: "By default, without any configuration, everything you exchange with the outside is immutable.". This behaviour seems sane. ''
Line 165: Line 118:
''Note: The publish option is aimed at controlling the behavior of *server*. Changeset in any state on a publishing server will **always*** be seen as public by other client. "Passive" repository which are only used as server for pull and push operation are not "affected" by this section. ''
Line 166: Line 120:
Note: The publish option is aimed at controlling the behavior of *server*.
Changeset in any state on a publishing server will **always*** be seen as public
by other client. "Passive" repository which are only used as server for pull and
push operation are not "affected" by this section.
''As in the choice for default, the main reason to allow draft changeset in publishing server is backward compatibility. With an old client, the following scenario is valid:: ''
Line 171: Line 122:
As in the choice for default, the main reason to allow draft changeset in
publishing server is backward compatibility. With an old client, the following
scenario is valid::
 . ''~/A$ old-hg init ~/A$ echo 'babar' > jungle ~/A$ old-hg commit -mA 'X' ~/A$ old-hg qimport -r . # or any other mutable operation on X
Line 175: Line 124:
  ~/A$ old-hg init
  ~/A$ echo 'babar' > jungle
  ~/A$ old-hg commit -mA 'X'
  ~/A$ old-hg qimport -r . # or any other mutable operation on X
''
Line 180: Line 126:
If the default is publishing and new commits in such repository are "public" The
following operation will be denied as X will be an **immutable** public
changeset. However as other clients see X as public, any pull//push (or event
pull//pull) will mark X as public in repo A.
''If the default is publishing and new commits in such repository are "public" The following operation will be denied as X will be an **immutable** public changeset. However as other clients see X as public, any pull//push (or event pull//pull) will mark X as public in repo A. ''
Line 185: Line 128:
Allowing enforcement of public changeset only repository through config is
probably something to do. This could be done with another "strict" option or a
third value config for phase related option (mode=public, publishing(default),
mutable)

''Allowing enforcement of public changeset only repository through config is probably something to do. This could be done with another "strict" option or a third value config for phase related option (mode=public, publishing(default), mutable) ''
Line 193: Line 131:
----
'' ''
Line 194: Line 134:

----

(If you were looking to the developer oriented page: [[PhaseDevel]])
''(If you were looking to the developer oriented page: PhaseDevel) ''

Phases

1. Introduction

The phase concept improves safety of history rewriting and control over changesets exchanged (read more). This phase concept aims to "just works" in a transparent manner for any user (read more). It is part of Core and always enabled in any new client but doesn't prevent older client to work on a repository (read more). Advanced user may decides to handle phase manually (read more).

Like bookmarks, phases are not stored in history and thus are not permanent and leave no audit trail.

This concept is introduced in Mercurial 2.1.

2. Available Phases

The phase concept allow to:

  • Prevent accidental rewriting part of the history expected to be immutable.
  • Keep immature changeset to be exchanged by mistake.

To achieve this, are three phases sharing a hierarchy of traits:

immutable

shared

public

x

x

draft

x

secret

* The public phases holds changeset announced publicly in. They are expect to

  • always exists in your history and are said immutable. History rewriting extension will refuse to delete such immutable changeset. Every changeset your push or pull from a public server are set in this phase.

* The draft phase holds changesets that was not expect marked as part of

  • the permanent history. You can safely rewrite them. New commit are draft by default.

* The secret phase holds changeset that you do not want to exchange with

  • other repository. Secret changeset are hidden to remote peer and won't be included in push operation. Manual operation or Extension may turn changeset secret.

Phases split the history in coherent set of changeset. Every changeset in a phase have ancestor in a phase compatible with its phase. Compatible means an changeset ancestors have at least the same traits that the children changeset. eg: A shared changeset alway have shared ancestor and an immutable changeset always have immutable ancestors.

In other word the phase of a changeset is alway equal of higher that the phase of it's descendant. According to the following order:

  • public < draft < secret

A changeset is not expected to automatically move from a lower phase to an higher phase (eg: from public to draft) but automatic

3. Phase Movements

Phase movement are automatic and transparent and most user don't have to care much about them. The base rule is very simple:

  • Any changesets on a remote repository is seen a public

One standard exchange commands, the phase of changesets on both side are compared. If differ the lowest phase is choosed. (eg: a changeset known as draft locally but public remotely is set public localy. Because public < draft)

This update happen during standard exchange commands:

* pull: remote phase data are used to update the phase data on

  • the local repo. As pull is read only, it does not change changeset's phase on the remote

* push: remote phase data are used to the phase data on the local repo and

  • then local phase data are pushed to the local repo.

The real behavior is a it's a bit more complicated than changesets on a remote repository is seen a public, but this is true for repository keeping default . If you need a finer behavior, consult the publishing repository section.

New changeset committed locally are draft, but some extension like mq may create secret and handle the move from secret to draft automatically

Consult the #upgrade_Notes section to check how phase will move the first time a new version of Mercurial touch and existing repository.

4. command line interface

4.1. core command

4.2. impact on extension

5. Publishing Repository

By default any changeset exchanged over the wire are set public. Advanced user may want a finer behavior. The Publishing repository concept is designed for this purpose.

5.0.1. What is a "publishing repository"?

Setting a repository as "publishing" alter its behavior **when used as a server**: all changesets are **seen** as public changesets by clients.

So, pushing to a "publishing" repository is the most common way to make changesets public: pushed changesets are seen as public on the remote side and marked as such on local side.

Note: the "publishing" property have no effects for local operations.

5.0.2. Old repository are publishing

Phase is the first step of a series of features aiming at handling mutable history within mercurial. Old client do not support such feature and are unable to hold phase data. The safest solution is to consider as public any changeset going through an old client.

Moreover, most hosting solution will not support phase from the beginning. Having old clients seen as public repositories will not change their usage: public repositories where you push *immutable* public changesets *shared* with others.

5.0.3. Why is "publishing" the default?

We discussed above that any changeset from a non-phase aware repository should be seen as public. This means that in the following scenario, X is pulled as public::

  • ~/A$ old-hg init
    ~/A$ echo 'babar' > jungle
    ~/A$ old-hg commit -mA 'X'
    ~/A$ cd ../B
    ~/B$ new-hg pull ../A # let's pretend A is served by old-hg
    ~/B$ new-hg log -r tip
    • summary:     X phase:       public

We want to keep this behavior while creating/serving the A repository with new-hg. Although committing with any new-hg creates a draft changeset. To stay backward compatible, the pull must see the new commit as public. Non-publishing server will advertise them as draft. Having publishing repository the default is thus necessary to ensure this backward compatibility.

This default value can also be expressed with the following sentence: "By default, without any configuration, everything you exchange with the outside is immutable.". This behaviour seems sane.

5.0.4. Why allow draft changeset in publishing repository

Note: The publish option is aimed at controlling the behavior of *server*. Changeset in any state on a publishing server will **always*** be seen as public by other client. "Passive" repository which are only used as server for pull and push operation are not "affected" by this section.

As in the choice for default, the main reason to allow draft changeset in publishing server is backward compatibility. With an old client, the following scenario is valid::

  • ~/A$ old-hg init ~/A$ echo 'babar' > jungle ~/A$ old-hg commit -mA 'X' ~/A$ old-hg qimport -r . # or any other mutable operation on X

If the default is publishing and new commits in such repository are "public" The following operation will be denied as X will be an **immutable** public changeset. However as other clients see X as public, any pull//push (or event pull//pull) will mark X as public in repo A.

Allowing enforcement of public changeset only repository through config is probably something to do. This could be done with another "strict" option or a third value config for phase related option (mode=public, publishing(default), mutable)

6. Upgrade Notes


(If you were looking to the developer oriented page: PhaseDevel)

Phases (last edited 2014-12-04 14:50:53 by KimRandell)