Size: 10367
Comment:
|
Size: 10492
Comment: First pass to deal with crappy language.
|
Deletions are marked like this. | Additions are marked like this. |
Line 6: | Line 6: |
Phases improve safety of history rewriting and provide control over changesets exchanged among different repositories ([[#Available_Phases|read more]]). Phases are intended to transparently "just work" for most users ([[#Phase_Movements|read more]]). It is part of Core and always enabled in any new client but doesn't prevent older clients from working on a repository ([[#Upgrade_Notes|read more]]). Advanced users may decide to handle phases manually to provide finer control ([[#Publishing_Repository|read more]]). | Phases improve safety of history rewriting and provide control over changesets exchanged among different repositories ([[#Available_Phases|read more]]). Phases are intended to transparently "just work" for most users ([[#Phase_Movements|read more]]). Phases are a part of the core Mercurial client code, enabled in any new client without preventing older clients from working on a repository ([[#Upgrade_Notes|read more]]). Advanced users may decide to handle phases manually to provide finer control ([[#Publishing_Repository|read more]]). |
Line 8: | Line 8: |
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; as such, they're not permanent and leave no audit trail. |
Line 15: | Line 15: |
* Prevent accidental rewriting part of the history expected to be immutable. * Prevent immature changesets from being exchanged by mistake. |
* Prevent accidentally rewriting part of the history expected to be immutable * Prevent immature changesets from being exchanged by mistake |
Line 25: | Line 25: |
* '''The public phase''' holds changesets that have been exchanged publicly. Changesets in the public phase are expected to always exists in your history and are said ''immutable''. History rewriting extensions will refuse to delete these '''immutable''' changesets. Every changeset your push or pull from a public server is put in the public phase. | * '''The public phase''' holds changesets that have been exchanged publicly. Changesets in the public phase are expected to remain in your repository history and are said to be ''immutable''. History rewriting extensions will refuse to delete these '''immutable''' changesets. Every changeset you push or pull from or to a public server is put in the public phase. |
Line 29: | Line 29: |
* '''The secret phase''' holds changesets that you do not want to exchange with other repositories. Secret changesets are hidden from remote peers and will not be included in push operations. Manual operations or extensions may move the changeset to the secret phase. | * '''The secret phase''' holds changesets that you do not want to exchange with other repositories. Secret changesets are hidden from remote peers and will not be included in push operations. Manual operations or extensions may move a changeset into the secret phase. |
Line 31: | Line 31: |
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. | Phases split the history in a coherent set of changesets. Every changeset in a phase has an ancestor in a phase ''compatible'' with its phase. ''Compatible'' means an changeset's ancestors must at least have the same traits as the changeset itself, e.g.: a ''shared'' changeset always has ''shared'' ancestors and an ''immutable'' changeset always has ''immutable'' ancestors. |
Line 33: | Line 33: |
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: | In other word the phase of a changeset is always equal to or higher than the phase of it's descendants, according to the following order: |
Line 37: | Line 37: |
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 40: | Line 40: |
Phase movement are automatic and transparent and most user don't have to care much about them. The base rule is very simple: | Phase movements are automatic and transparent; most users don't have to care much about them. The base rule is very simple: |
Line 42: | Line 42: |
. "''Any changesets on a remote repository is seen as public''" | . "''Any changesets seen in a remote repository are public''" |
Line 44: | Line 44: |
On 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) | On standard exchange commands, phases of changesets on both sides are compared. If phases on both sides are not equal, the lowest phase is chosen, e.g.: a changeset known as ''draft'' locally but '''public''' remotely is set to public locally, because public < draft in the phase hierarchy. |
Line 46: | Line 46: |
This update happen during standard exchange commands: | This update happens during standard exchange commands: |
Line 48: | Line 48: |
* '''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 | * '''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 phases on the remote |
Line 50: | Line 50: |
* '''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 update the phase data on the local repo, then local phase data are pushed to the local repo |
Line 52: | Line 52: |
The real behavior is a it's a bit more complicated than '' changesets on a remote repository is seen as public'', but this is true for repository keeping default . If you need a finer behavior, consult the ''[[#Publishing_Repository|publishing repository]]'' section. | The real behavior is a bit more complicated than ''changesets on a remote repository are seen as public'', but this is true for simple repository setups. If you need finer-grained behavior, consult the section on ''[[#Publishing_Repository|publishing repositories]]''. |
Line 54: | Line 54: |
New changeset committed locally are ''draft'', but some extension like ''mq'' may create ''secret'' and handle the move from ''secret'' to ''draft'' automatically | New changesets committed locally are in the ''draft'' phase, but some extensions (like ''mq'') may create ''secret'' changesets and handle the move from ''secret'' to ''draft'' in some other way. |
Line 56: | Line 56: |
Consult the [[#upgrade_Notes]] section to check how phase will move the first time a new version of Mercurial touch and existing repository. | Consult the [[#upgrade_Notes]] section to check how phases will move the first time a new version of Mercurial touches an existing repository. |
Line 60: | Line 60: |
The phase are intended to be transparent, for most user. People should not need to manually handle them and won't meet any behavior changes except to prevent common mistake. But some people might want to have a fine control on their phase and manually handle them. This section describe how to do change phase and what is the exact impact on phase on common operation. |
Phases are intended to be transparent for most users. People should not need to manually handle them and won't generally run into any behavior changes except to prevent common mistakes. Advanced users may want finer control over phase changes; this section describes how to change phases manually. |
Line 70: | Line 64: |
The phase concept introduce a single new command: {{{phase}}}. This command will allow to see and change phases of changeset. | The phase concept introduce a single new command: {{{phase}}}. This command will allow users to see and change phases of changesets. |
Line 92: | Line 86: |
the {{{hg log}}} command display phase of changeset when --debug is used | The {{{hg log}}} command displays changeset phases when --debug is used. |
Line 94: | Line 88: |
All commands related to changeset exchange will ignore secret changeset. This applies to: |
All commands related to changeset exchange will ignore secret changesets, including: |
Line 104: | Line 97: |
A nice message will be displayed when outgoing operation (outgoing, push, bundle) fails to push anything but there is unsynchronized secret changeset. |
A warning will be displayed when outgoing operation (outgoing, push, bundle) fails to push anything in the face of unsynchronized secret changesets. |
Line 111: | Line 103: |
Note that when using the {{{--base}}} option of bundle. Secret changeset are included. |
Note that when using the {{{--base}}} option of bundle, secret changeset are included. |
Line 116: | Line 107: |
Extensions that rewrite history like, MQ, rebase, collapse or histedit will refuse to work on immutable changeset. When trying to work with them on public changeset you are expected to meet the following error: |
Extensions that rewrite history (like MQ, rebase, collapse or histedit) will refuse to work on immutable changesets. When applying any of these extensions to a public changeset, an error will be thrown: |
Line 121: | Line 111: |
abort revision 8184 is not mutable | abort: revision 8184 is not mutable |
Line 125: | Line 115: |
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 protocol is set to public. Advanced users may want some other behavior; the publishing repository concept is designed for this purpose. |
Line 128: | Line 118: |
Setting a repository as "publishing" alter its behavior **when used as a server**: all changesets are **seen** as public changesets by clients. | Setting a repository as "publishing" alters its behavior **when used as a server**: all changesets in the repository are **seen** as public changesets by clients. |
Line 132: | Line 122: |
Note: the "publishing" property have no effects for local operations. | Note: the "publishing" property has no effects for local operations. |
Line 135: | Line 125: |
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. | Phase is the first step of a series of features aimed at better handling mutable history within Mercurial. Old clients do not support this feature and are unable to keep track of phase data. The safest solution is to consider as public any changeset going through an old client. |
Line 137: | Line 127: |
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 solutions will not support phases 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 148: | Line 138: |
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. | 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 servers will advertise them as draft. Having publishing repository be the default is thus necessary to ensure this backward compatibility. |
Line 150: | Line 140: |
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". |
Line 173: | Line 163: |
* new client will add phase data to any repository it touches * If everything you plan to mutate is handled by MQ you don't have to care about anything. |
* the new client will add phase data to any repository it touches * if everything you plan to mutate is handled by MQ you don't have to care about anything |
Line 178: | Line 168: |
Phase data are stored in a new files and does not alter any part of the existing mercurial repository format. This means that a new client can safely write phase related data without preventing an old client to works with the repository. This allow new client store and handle phase related logic on **all repository**. |
Phase data are stored in a new file and do not alter any part of the existing Mercurial repository format. This means that a new client can safely write phase related data without preventing an old client to work with the repository. This allows new client to store and handle phase related logic on **all repositories**. |
Line 185: | Line 175: |
There are a lot a repository out there with plenty of changeset but yet any phase data. When looking at such repository, a new client take the safe road and decided everything is 'public'. Some extension register logic to tune this choice. For example, mq set every changeset under it's control as secret in this |
There are a lot a repositories out there with plenty of changeset but lacking any phase data. When looking at such a repository, a new client will take the safe road and decide everything is 'public'. Some extensions register logic to tune this choice; for example, mq will set every changeset under it's control as secret in this |
Line 200: | Line 190: |
Beware that and old client won't be able to move phase when touching a repo. | Beware that any old client won't be able to move phases when touching a repo |
Line 202: | Line 192: |
* An old client can mutable immutable changesets * An old client will push secret changeset * An old client will commit new changeset in the phase of their parent * An old client add changeset in the phase of their parent. |
* An old client can mutate immutable changesets * An old client will push secret changesets * An old client will commit new changesets in the phase of their parent * An old client will add changeset in the phase of their parent |
Phases
Contents
1. Introduction
Phases improve safety of history rewriting and provide control over changesets exchanged among different repositories (read more). Phases are intended to transparently "just work" for most users (read more). Phases are a part of the core Mercurial client code, enabled in any new client without preventing older clients from working on a repository (read more). Advanced users may decide to handle phases manually to provide finer control (read more).
Like bookmarks, phases are not stored in history; as such, they're not permanent and leave no audit trail.
Phases are introduced in Mercurial 2.1.
2. Available Phases
Phases are used to:
- Prevent accidentally rewriting part of the history expected to be immutable
- Prevent immature changesets from being exchanged by mistake
To achieve this, three phases share a hierarchy of traits:
|
immutable |
shared |
public |
x |
x |
draft |
|
x |
secret |
|
|
The public phase holds changesets that have been exchanged publicly. Changesets in the public phase are expected to remain in your repository history and are said to be immutable. History rewriting extensions will refuse to delete these immutable changesets. Every changeset you push or pull from or to a public server is put in the public phase.
The draft phase holds changesets that are not yet considered a part of the repository's permanent history. You can safely rewrite them. New commits are in the draft phase by default.
The secret phase holds changesets that you do not want to exchange with other repositories. Secret changesets are hidden from remote peers and will not be included in push operations. Manual operations or extensions may move a changeset into the secret phase.
Phases split the history in a coherent set of changesets. Every changeset in a phase has an ancestor in a phase compatible with its phase. Compatible means an changeset's ancestors must at least have the same traits as the changeset itself, e.g.: a shared changeset always has shared ancestors and an immutable changeset always has immutable ancestors.
In other word the phase of a changeset is always equal to or higher than the phase of it's descendants, 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 movements are automatic and transparent; most users don't have to care much about them. The base rule is very simple:
"Any changesets seen in a remote repository are public"
On standard exchange commands, phases of changesets on both sides are compared. If phases on both sides are not equal, the lowest phase is chosen, e.g.: a changeset known as draft locally but public remotely is set to public locally, because public < draft in the phase hierarchy.
This update happens 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 phases on the remote
push: remote phase data are used to update the phase data on the local repo, then local phase data are pushed to the local repo
The real behavior is a bit more complicated than changesets on a remote repository are seen as public, but this is true for simple repository setups. If you need finer-grained behavior, consult the section on publishing repositories.
New changesets committed locally are in the draft phase, but some extensions (like mq) may create secret changesets and handle the move from secret to draft in some other way.
Consult the #upgrade_Notes section to check how phases will move the first time a new version of Mercurial touches an existing repository.
4. Command line interface
Phases are intended to be transparent for most users. People should not need to manually handle them and won't generally run into any behavior changes except to prevent common mistakes. Advanced users may want finer control over phase changes; this section describes how to change phases manually.
4.1. Core Command
The phase concept introduce a single new command: phase. This command will allow users to see and change phases of changesets.
$ hg phase -r 8183::8186 8183: public 8184: public 8185: secret 8186: secret
$ hg phase -v --draft 8185 phase change for 1 changesets $ hg phase -r 8183::8186 8183: public 8184: public 8185: draft 8186: secret
See the command documentation for details.
The hg log command displays changeset phases when --debug is used.
All commands related to changeset exchange will ignore secret changesets, including:
- push
- pull
- incoming
- outgoing
- bundle
- clone
A warning will be displayed when outgoing operation (outgoing, push, bundle) fails to push anything in the face of unsynchronized secret changesets.
no changes to push but 7 secret changesets
Note that when using the --base option of bundle, secret changeset are included.
4.2. Impact on extension(s)
Extensions that rewrite history (like MQ, rebase, collapse or histedit) will refuse to work on immutable changesets. When applying any of these extensions to a public changeset, an error will be thrown:
abort: revision 8184 is not mutable
5. Publishing Repository
By default, any changeset exchanged over the wire protocol is set to public. Advanced users may want some other behavior; the publishing repository concept is designed for this purpose.
5.0.1. What is a "publishing repository"?
Setting a repository as "publishing" alters its behavior **when used as a server**: all changesets in the repository 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 has no effects for local operations.
5.0.2. Old repository are publishing
Phase is the first step of a series of features aimed at better handling mutable history within Mercurial. Old clients do not support this feature and are unable to keep track of phase data. The safest solution is to consider as public any changeset going through an old client.
Moreover, most hosting solutions will not support phases 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$ 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 servers will advertise them as draft. Having publishing repository be 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".
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.
6. Upgrade Notes
The important points to remember are:
- repositories with phase data can still be accessed by old client(s)
- the new client will add phase data to any repository it touches
- if everything you plan to mutate is handled by MQ you don't have to care about anything
6.1. Backward Compatility
Phase data are stored in a new file and do not alter any part of the existing Mercurial repository format. This means that a new client can safely write phase related data without preventing an old client to work with the repository. This allows new client to store and handle phase related logic on **all repositories**.
6.2. Adding phase data to old repo
There are a lot a repositories out there with plenty of changeset but lacking any phase data. When looking at such a repository, a new client will take the safe road and decide everything is 'public'. Some extensions register logic to tune this choice; for example, mq will set every changeset under it's control as secret in this situation.
You can set all changesets not pushed to a repository in the draft phase again using:
hg phase --force --draft 'outgoing()'
6.3. Adding phase data to old repo
Beware that any old client won't be able to move phases when touching a repo
- An old client can mutate immutable changesets
- An old client will push secret changesets
- An old client will commit new changesets in the phase of their parent
- An old client will add changeset in the phase of their parent
(If you were looking for the developer oriented page: PhaseDevel)