# HG changeset patch # User Pierre-Yves.David@ens-lyon.org # Date 1336729935 -7200 # Node ID 2f68c708e10b3959e7bdf369aba2c5f1b6045901 # Parent 1fc4299ca8e2c4ba7ea4aaeb87aa8960f479a85c fix typo in file name diff -r 1fc4299ca8e2 -r 2f68c708e10b docs/index.rst --- a/docs/index.rst Fri May 11 11:42:59 2012 +0200 +++ b/docs/index.rst Fri May 11 11:52:15 2012 +0200 @@ -12,7 +12,7 @@ .. toctree:: :maxdepth: 2 - unstability + instability The effort is splits in two parts: diff -r 1fc4299ca8e2 -r 2f68c708e10b docs/instability.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/instability.rst Fri May 11 11:52:15 2012 +0200 @@ -0,0 +1,218 @@ + +----------------------------------- +The instability Principle +----------------------------------- + + + +An intrinsic contradiction +----------------------------------- + +XXX starts by talking about getting ride of changeset. + +DVCS bring two new major concepts to the Version Control Scene: + + * History is organized as a robust DAG, + * History can be rewritten. + + +However, the two concepts are in contradiction: + +To achieve a robust history, three key elements are gathered in *changeset*: + + * Full snapshot of the versioned content, + * Reference to the previous full snapshot used to build the new one, + * A description of the change who lead from the old content to the new old. + +All three elements are to compute a *unique* hash that identify the changeset +(with various other metadata). This identification is a key part of DVCS design. + +This is a very useful property because Changing B parent means changing B +content too. This require the creation of **another** changeset which is a good +semantic. + +:: + + Schema base, A, B and B' + +To avoid duplication, the older changeset is usually discarded from accessible +history. I'm calling them *obsolete* changesets. + + +But rewriting a changeset with children does not changes children parent! And +because children of the rewritten changeset still **depends** on the older +"dead" version of the changeset with can not get ride of this dead version. + +:: + + Schema base, A and A' and B. + +I'm calling those children **unstable** because they are based one a dead +changeset and prevent people to get ride of it. + +This instability is an **unavoidable consequence** of the strict dependency of +changeset. History Rewriting history alway need to take it in account and +provide a way to rewrite the descendant on the new changeset to avoid +coexistence of the old and new version of a rewritten changeset.. + + +Everybody is working around the issue +------------------------------------------------ + +I'm not claiming that rewriting history is impossible. People are successfully +doing for years. However they all need to work around *instability*. Several +work around strategy exists. + + +Rewriting all at once +`````````````````````````` + +The simplest way to avoid instability is to ensure rewriting operation always +ends in a stable situation. This is achieve by rewriting all impacted changeset +at the same time. + +Rewriting all descendants at the same time than the rewritted of a changeset. + +:: + + Schema! + +Several Mercurial commands apply it: rebase, collapse, histedit. Mercurial also +refuse to amend changeset with descendant. The git branch design enforce such +approach in git too. + + +However, DVCS are **Distributed**. This means that you do not control what +happen outside your repository. Once a changeset have been exchanged *outside*, +there is no way to be sure it does not have descendants somewhere else. +Therefore **if you rewrite changeset that exists elsewhere, you can't eradicate +the risk of instability.** + +Do not rewrite exchanged changeset +``````````````````````````````````` + +To work around the issue above, mercurial introduced phases that prevent you to +rewrite shared changeset and ensure other can't pull certain changeset from you. +But this is a very frustrating limitation that prevent you to efficiently share, +review and collaborate on mutable changeset. + +Git world use another approach to prevent instability. By convention only a +single developper works on a changeset contained in a named branch. But once +again this is a huge blocker for collaborating. Moreover clueless people +**will** mess up social convention soon or later. + + +Loose the DAG robustness +```````````````````````````` + +The other approach use in Mercurial is to keep the mutable part of the history +outside the DVCS constraint. This is the MQ approach of sticking a quilt queue +over Mercurial. + +This allow much more flexible workflow but two major feature are lost in the +process: + +:Graceful merge: MQ use plain-patch to store changeset content and patch have + trouble to apply in changing context. Applying your queue + becomes very painful when context changes. + +:easy branching: A quilt queue is by definition a linear queue. Increasing risk + of conflict + +It is possible to collaborate over versioned mq! But you are going ahead a lot +of troubles. + +.. Ignore conflicts +.. ``````````````````````````````````` +.. +.. Another ignored issue is conflicting rewritting of the same changeset. If a +.. changeset is rewritten two times we have two newer version, duplicated history +.. complicate to merge. +.. +.. Mercurial work around by +.. +.. The "One set of mutable changset == One developper" mantra is also a way to work +.. around conflicting rewritting of changeset. If two different people are able to +.. +.. The git branch model allow to overwrite changeset version by another one. But it +.. does not care about divergent version. It is the equilent of "common ftp" source +.. management for changeset. + +Facing The Danger Once And For All +------------------------------------------------ + +Above we saw that, the more effort you put to avoid instability, the more option +you deny. And even most restrictive work flow can't guarantee that instability +will never show up! + +Obsolete marker can handle the job +``````````````````````````````````` + +It is time to provide a full featured solution to deal with instability and to +stop working around the issue! This is why I developing a new feature for +mercurial called "Obsolete markers". Obsolete markers have two key properties: + + +* Any "old" changeset we want to get ride of is **explicitly** marked as "obsolete" + by history rewriting operation. + + By explicitly marking the obsolete part of the history, we will be able to + easily detect instability situation. + +* Relations between old and new version of changesets are tracked by obsolete + markers. + + By Storing a meta-history of changeset evolution we are able to easily resolve + instability and edition conflict [#]_ . + +.. [#] edition conflict is another major obstable to collaboration. See the + section dedicated to obsolete marker for details. + +Improves robustness == improves simplicity +```````````````````````````````````````````````` + +This proposal should **first** be seen as a safety measure. + +It allow to detect instability as soon as possible + +:: + + $ hg pull + added 3 changeset + +2 unstable changeset + (do you want "hg stabilize" ?) + working directory parent is obsolete! + $ hg push + outgoing unstable changesets + (use "hg stabilize" or force the push) + +And should not not encourage people to create unstability + +:: + + $ hg up 42 + $ hg commit --amend + changeset have descendant. + $ hg commit --amend -f + +5 unstable changeset + + $ hg rebase -D --rev 40::44 + rebasing already obsolete changeset 42:AAA will conflict with newer version 48:BBB + +While allowing powerful feature +```````````````````````````````````````````````` + + +* Help to automatically solve instability. + +* "kill" changeset remotely. + +* track resulting changeset when submitting patch//pull request. + +* Focus on what you do: + + I do not like the "all at once" model of history rewriting. I'm comfortable + with unstability and obsolete marker offer all the tool to safely create and + handle unstability locally. + + diff -r 1fc4299ca8e2 -r 2f68c708e10b docs/unstability.rst --- a/docs/unstability.rst Fri May 11 11:42:59 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ - ------------------------------------ -The instability Principle ------------------------------------ - - - -An intrinsic contradiction ------------------------------------ - -XXX starts by talking about getting ride of changeset. - -DVCS bring two new major concepts to the Version Control Scene: - - * History is organized as a robust DAG, - * History can be rewritten. - - -However, the two concepts are in contradiction: - -To achieve a robust history, three key elements are gathered in *changeset*: - - * Full snapshot of the versioned content, - * Reference to the previous full snapshot used to build the new one, - * A description of the change who lead from the old content to the new old. - -All three elements are to compute a *unique* hash that identify the changeset -(with various other metadata). This identification is a key part of DVCS design. - -This is a very useful property because Changing B parent means changing B -content too. This require the creation of **another** changeset which is a good -semantic. - -:: - - Schema base, A, B and B' - -To avoid duplication, the older changeset is usually discarded from accessible -history. I'm calling them *obsolete* changesets. - - -But rewriting a changeset with children does not changes children parent! And -because children of the rewritten changeset still **depends** on the older -"dead" version of the changeset with can not get ride of this dead version. - -:: - - Schema base, A and A' and B. - -I'm calling those children **unstable** because they are based one a dead -changeset and prevent people to get ride of it. - -This instability is an **unavoidable consequence** of the strict dependency of -changeset. History Rewriting history alway need to take it in account and -provide a way to rewrite the descendant on the new changeset to avoid -coexistence of the old and new version of a rewritten changeset.. - - -Everybody is working around the issue ------------------------------------------------- - -I'm not claiming that rewriting history is impossible. People are successfully -doing for years. However they all need to work around *instability*. Several -work around strategy exists. - - -Rewriting all at once -`````````````````````````` - -The simplest way to avoid instability is to ensure rewriting operation always -ends in a stable situation. This is achieve by rewriting all impacted changeset -at the same time. - -Rewriting all descendants at the same time than the rewritted of a changeset. - -:: - - Schema! - -Several Mercurial commands apply it: rebase, collapse, histedit. Mercurial also -refuse to amend changeset with descendant. The git branch design enforce such -approach in git too. - - -However, DVCS are **Distributed**. This means that you do not control what -happen outside your repository. Once a changeset have been exchanged *outside*, -there is no way to be sure it does not have descendants somewhere else. -Therefore **if you rewrite changeset that exists elsewhere, you can't eradicate -the risk of instability.** - -Do not rewrite exchanged changeset -``````````````````````````````````` - -To work around the issue above, mercurial introduced phases that prevent you to -rewrite shared changeset and ensure other can't pull certain changeset from you. -But this is a very frustrating limitation that prevent you to efficiently share, -review and collaborate on mutable changeset. - -Git world use another approach to prevent instability. By convention only a -single developper works on a changeset contained in a named branch. But once -again this is a huge blocker for collaborating. Moreover clueless people -**will** mess up social convention soon or later. - - -Loose the DAG robustness -```````````````````````````` - -The other approach use in Mercurial is to keep the mutable part of the history -outside the DVCS constraint. This is the MQ approach of sticking a quilt queue -over Mercurial. - -This allow much more flexible workflow but two major feature are lost in the -process: - -:Graceful merge: MQ use plain-patch to store changeset content and patch have - trouble to apply in changing context. Applying your queue - becomes very painful when context changes. - -:easy branching: A quilt queue is by definition a linear queue. Increasing risk - of conflict - -It is possible to collaborate over versioned mq! But you are going ahead a lot -of troubles. - -.. Ignore conflicts -.. ``````````````````````````````````` -.. -.. Another ignored issue is conflicting rewritting of the same changeset. If a -.. changeset is rewritten two times we have two newer version, duplicated history -.. complicate to merge. -.. -.. Mercurial work around by -.. -.. The "One set of mutable changset == One developper" mantra is also a way to work -.. around conflicting rewritting of changeset. If two different people are able to -.. -.. The git branch model allow to overwrite changeset version by another one. But it -.. does not care about divergent version. It is the equilent of "common ftp" source -.. management for changeset. - -Facing The Danger Once And For All ------------------------------------------------- - -Above we saw that, the more effort you put to avoid instability, the more option -you deny. And even most restrictive work flow can't guarantee that instability -will never show up! - -Obsolete marker can handle the job -``````````````````````````````````` - -It is time to provide a full featured solution to deal with instability and to -stop working around the issue! This is why I developing a new feature for -mercurial called "Obsolete markers". Obsolete markers have two key properties: - - -* Any "old" changeset we want to get ride of is **explicitly** marked as "obsolete" - by history rewriting operation. - - By explicitly marking the obsolete part of the history, we will be able to - easily detect instability situation. - -* Relations between old and new version of changesets are tracked by obsolete - markers. - - By Storing a meta-history of changeset evolution we are able to easily resolve - instability and edition conflict [#]_ . - -.. [#] edition conflict is another major obstable to collaboration. See the - section dedicated to obsolete marker for details. - -Improves robustness == improves simplicity -```````````````````````````````````````````````` - -This proposal should **first** be seen as a safety measure. - -It allow to detect instability as soon as possible - -:: - - $ hg pull - added 3 changeset - +2 unstable changeset - (do you want "hg stabilize" ?) - working directory parent is obsolete! - $ hg push - outgoing unstable changesets - (use "hg stabilize" or force the push) - -And should not not encourage people to create unstability - -:: - - $ hg up 42 - $ hg commit --amend - changeset have descendant. - $ hg commit --amend -f - +5 unstable changeset - - $ hg rebase -D --rev 40::44 - rebasing already obsolete changeset 42:AAA will conflict with newer version 48:BBB - -While allowing powerful feature -```````````````````````````````````````````````` - - -* Help to automatically solve instability. - -* "kill" changeset remotely. - -* track resulting changeset when submitting patch//pull request. - -* Focus on what you do: - - I do not like the "all at once" model of history rewriting. I'm comfortable - with unstability and obsolete marker offer all the tool to safely create and - handle unstability locally. - -