# HG changeset patch # User Pierre-Yves David # Date 1332863469 -7200 # Node ID 8e2d9918c886e8747f90eb1f8501cd576eb20486 # Parent 9cbb6756485c485b4cc8894dd5c9d9a4e24bcbda# Parent 4d44a37d51d148adacfb44d48543bc301b7d66ff merge diff -r 9cbb6756485c -r 8e2d9918c886 docs/obs-concept.rst --- a/docs/obs-concept.rst Tue Mar 27 17:39:34 2012 +0200 +++ b/docs/obs-concept.rst Tue Mar 27 17:51:09 2012 +0200 @@ -2,51 +2,54 @@ Why Do We Need a New Concept ----------------------------------------------------------- -Current DVCS are great tool to forge a series of flawless changeset on your own. -But they perform poorly whe is comes to **share** work in progress and -**collaborate** on such work in progress. +Current DVCS are great tools to forge a series of flawless changeset on your own. +But they perform poorly when it comes to **sharing** some work in progress and +**collaborating** on such work in progress. -When people forge new version of a changeset they create a new changeset and get -ride of the original changeset. Difficultis to collaborate mostly came from the -way old content are *removed* from repository. +When people forge a new version of a changeset they actually create a +new changeset and get rid of the original changeset. Difficultis to +collaborate mostly came from the way old content is *removed* from +a repository. Mercurial Approach: Strip ----------------------------------------------------- -With current version of mercurial, every changesets that exist in your -repository are *visible* and *meaningful*. To get ride of old changeset you -rewrote mercurial remove them from the repository storage. with an operation -called *strip*. After the *strip* the repository looks like if the changeset -never existed. +With the current version of mercurial, every changeset that exists in +your repository is *visible* and *meaningful*. To delete old +(rewritten) changesets, mercurial removes them from the repository +storage with an operation called *strip*. After the *stripping*, the +repository looks like if the changeset never existed. -This approach is simple and effective but have a very big drawnback: You can -remove changesets from **your repository only**. If strip exists in other -repositories it will show of again and again. This only cure for this is to -strip the offending changeset from all repository. And operation at best -impractical and in most case impossible! - +This approach is simple and effective except there is a very big +drawback: you can remove changesets from **your repository only**. If +a stripped changeset exists in another repository it touches, it will +show up again. This is because a shared changeset becomes +part of a shared global history. Stripping a changeset from all +repositories is at best impractical and in most case impossible! As consequence, **you can not rewrite something once you exchange it with -others**. The old version will still exists along side the new one [#]_. +others**. The old version will still exist along side the new one [#]_. -Moreover backup are create stripped changeset in most case. This allow -restoration of old changeset but the process is painful. +However backups are created while stripping a changeset in most +cases. This allow restoration of an old changeset but the process is +painful. -Finally, as the repository format is not optimized for deletion. stripping a -changeset may be slow in some situation. - +Finally, as the repository format is not optimized for deletion, +stripping a changeset may be slow in some situation. -To sum up, the strip approach is very simple but does not handle interaction -with the outer world. Which is unfortunate for a *Distributed* VCS. +To sum up, the strip approach is very simple but does not handle +interaction with the outer world, which is very unfortunate for a +*Distributed* VCS. -.. [#] various work around exists but they are work around with their own flow. +.. [#] various workarounds exist but they are workarounds with their own flow. Git Approach: Overwrite Reference ----------------------------------------------------- -Git approach for repository is a bit more complex: They can be any amount of -changeset can exist in a repository. but **only changesets referenced by a git -branch** are *visible* and *meaningful*. +The Git approach to repository structure is a bit more complex: there +can be any amount of unrelated changesets in a repository, and **only +changesets referenced by a git branch** are *visible* and +*meaningful*. .. warning:: add a schema:: @@ -59,27 +62,26 @@ Only B and A are visible. -This ease the process of getting ride of old changeset. You can just leave them -in place and move the reference on the new one. You can then propagate those -change by moving the git-branch on remote host, newer version overwritting the -older one. +This ease the process of getting rid of old changesets. You can just +leave them in place and move the reference on the new one. You can +then propagate those changes by moving the git-branch on remote host, +the newer versions overwritting the older ones. -This approach goes a bit further but still have major drawback: - +This approach goes a bit further but still have a major drawback: -Because you **overwrite** git-branch you have no conflit resolution. The last -to spoke win. This make collaboration on multiple changeset difficult because -you can't merge concurent update on changeset. +Because you **overwrite** git-branch you have no conflit resolution. The last +to speak wins. This makes collaboration on multiple changesets difficult because +you can't merge concurent updates on a changeset. -Every overwrite is forced operation where the operator say "Yes I want this to -replace that. On higly distributed environment user may end with conflicting -reference with and no proper way to choose. +Every overwrite is a forced operation where the operator says "Yes I +want this to replace that". On a higly distributed environment, a user may +end with conflicting references and with no proper way to choose. -Because of this way to visualize a repository, git-branches are a very core -part of git. This make user interface more complicated and move through history -more constrainted. +Because of this way to visualize a repository, git-branches are a very +core part of git. This makes the user interface more complicated and +moving through history more constrained. -Finally, even if all older changeset still exist in the repository acces to them +Finally, even if all older changesets still exist in the repository, accesing them is still painful. @@ -88,20 +90,15 @@ ----------------------------------------------------- - - - -As None of the concept was powerful enough to embrace the need to safely rewrite -history, easily share and collaborate on mutable history we needed another one. - - +As none of these concepts were powerful enough to embrace the need to +safely share rewritten history we needed another one. Basic concept ----------------------------------------------------- -Every history rewriting operation stores the information that old rewritten -changesets has newer version available in a set of changeset. +Every history rewriting operation stores the information that old rewritten +changesets has a newer version available in a set of changesets. All basic history rewriting operation can create a appropriate obsolete marker. @@ -154,44 +151,47 @@ versioned files but applied to changeset: First: we can display a **coherent view** of the history graph with only a -single version of your changeset are displayed by the UI. - -Second, because obsolete changeset content are still **available**. You can +single version of your changeset displayed by the UI. - * **browse** the content of your obsolete commit, +Second, because obsolete changeset contents are still **available**, +you can - * **compare** newer and older version of a changeset, + * **browse** the contents of your obsolete commits, + + * **compare** newer and older versions of a changeset, - * **restore** content of previously obsolete changeset. + * **restore** contents of previously obsolete changesets. -Finally, obsolete marker can be **exchanged between repositories**. You are able to -share the result on your history rewriting operation with other and **collaborate -on mutable part of the history**. +Finally, the obsolete marker can be **exchanged between +repositories**. You are able to share the result on your history +rewriting operations with other prople and **collaborate on the +mutable part of the history**. -Conflicting history rewriting operation can be detected and **resolved** as easily -as conflicting changes on file. +Conflicting history rewriting operation can be detected and +**resolved** as easily as conflicting changes on a file. -Detecting and solving tricky situation +Detecting and solving tricky situations ----------------------------------------------------- -History rewriting can lead to complex situation. Obsolete marker introduce a -simple representation this complex reality. But people using complex workflow -will one day or another you have to face the intrinsics complexity of some -situation. +History rewriting can lead to complex situations. The obsolete marker +introduces a simple representation for this complex reality. But +people using complex workflows will one day or another have to face +the intrinsic complexity of some real-world situation. -This section describe possible situations, define precise set of changesets -involved in such situation and explains how error case can we automatically -resolved using available information. +This section describes possible situations, define precise sets of +changesets involved in such situations and explains how the error +cases can be automatically resolved using available information. -obsolete changesets +Obsolete changesets ```````````````````` Old changesets left behind by obsolete operation are said **obsolete**. -With current version of mercurial, this *obsolete* part is stripped from the -repository before the end of every rewritting operation. +With the current version of mercurial, this *obsolete* part is +stripped from the repository before the end of every rewritting +operation. .. figure:: ./figures/error-obsolete.* @@ -201,16 +201,16 @@ changesets. These Two old changesets are now part of the *obsolete* part of the history. -In most case the obsolete set will be fully hidden to both UI and discovery so -user do not have to care about them unless he wants to audit history rewriting -operation. +In most cases the obsolete set will be fully hidden to both the UI and +discovery, hence users do not have to care about them unless they want to +audit history rewriting operations. Unstable changesets ``````````````````` -While exploring obsolete marker possibility a bit further you way end up with -*obsolete* changeset with *non-obsolete* children. There is two common ways to -achieve this: +While exploring the obsolete marker possibility a bit further you may +end up with *obsolete* changeset with *non-obsolete* children. There +are two common ways to achieve this: * Pull a changeset based of an old version of a changeset [#]_. @@ -230,9 +230,10 @@ parent (`A`) is `A'`, We can deduce that we should rebase `B` on `A'` to get a stable history again. -Proper warning should be issued when part of the history become unstable. UI -will be able to use the obsolete marker to automatically suggest resolution to -the user of even carry them out for him. +Proper warnings should be issued when part of the history becomes +unstable. The UI will be able to use the obsolete marker to +automatically suggest a resolution to the user of even carry them out +for him. XXX details automatic resolution for @@ -247,11 +248,11 @@ .. [#] For this to happen one needs to explicitly enable exchange of draft changeset. See phase help for details. -The two part of the obsolete set +The two parts of the obsolete set `````````````````````````````````````` -The previous section show that it could be two kinds of *obsolete* changeset: - +The previous section shows that there could be two kinds of *obsolete* +changesets: * *obsolete* changeset with no or *obsolete* only descendants, said **extinct**. @@ -277,7 +278,7 @@ `````````````````````` If people start to concurrently edit the same part of the history they will -likely meet conflicting situation when a changeset have been rewritten in two +likely meet conflicting situations when a changeset have been rewritten in two different versions. @@ -285,17 +286,18 @@ Conflicting rewriting of `A` into `A'` and `A''` -This kind of conflict is easy to detect with obsolete marker because an obsolete -changeset have more than one new version. It may be seen as the multiple heads -case Mercurial warn you about on pull. It is resolved the same way by a merge of -A' and A'' that will keep the same parent than `A'` and `A''` with two obsolete +This kind of conflict is easy to detect with an obsolete marker +because an obsolete changeset can have more than one new version. It +may be seen as the multiple heads case. Mercurial warns you about this +on pull. It is resolved the same way by a merge of A' and A'' that +will keep the same parent than `A'` and `A''` with two obsolete markers pointing to both `A` and `A'` .. warning:: TODO: Add a schema of the resolution. (merge A' and A'' with A as ancestor and graft the result of A^) -Allowing multiple new changesets to obsolete a single one allow to distinct a -splitted changeset from history rewriting conflict. +Allowing multiple new changesets to obsolete a single one allows to +distinguish a split changeset from an history rewriting conflict. Reliable history `````````````````````` @@ -307,19 +309,18 @@ public changeset, but they is still some corner case where changesets rewritten in the past are made public. -Special rules apply for obsolete marker pointing to public changeset +Special rules apply for obsolete marker pointing to public changeset: -* Public changesets are excluded from the obsolete set (public changeset are - never hidden or candidate to garbage collection) +* Public changesets are excluded from the obsolete set (public + changesets are never hidden or candidate to garbage collection) -* *newer* version of public changeset are said **latecomer** and highlighted as - error case. - +* *newer* version of a public changeset are said **latecomer** and highlighted as + an error case. -Solving such error is easy. Because we know what changeset a *latecomer* try to -rewrite, we can easily compute a smaller changeset containing only the change -from the old *public* to the new *latecomer*. - +Solving such an error is easy. Because we know what changeset a +*latecomer* tries to rewrite, we can easily compute a smaller +changeset containing only the change from the old *public* to the new +*latecomer*. .. warning:: add a schema @@ -327,7 +328,7 @@ Conclusion ---------------- -Obsolete marker is a powerful concept that allow mercurial to safely handle +Obsolete marker is a powerful concept that allows mercurial to safely handle history rewriting operations. It is a new type of relation between Mercurial changesets that track the result of history rewriting operations.