Mercurial > evolve
changeset 367:5bc3e5dc2637
merge with doc fix
author | Pierre-Yves.David@ens-lyon.org |
---|---|
date | Sun, 15 Jul 2012 14:51:52 +0200 |
parents | ac7969043677 (current diff) c67af39d1ae9 (diff) |
children | de3d112db51b |
files | docs/evolve-faq.rst docs/from-mq.rst docs/glossary.rst docs/tutorials/tutorial.t |
diffstat | 14 files changed, 511 insertions(+), 311 deletions(-) [+] |
line wrap: on
line diff
--- a/docs/evolve-collaboration.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/evolve-collaboration.rst Sun Jul 15 14:51:52 2012 +0200 @@ -4,8 +4,9 @@ ------------------------------------------------ -After having written some code for ticket #42, M W. start a patch (this -will be kind of like a 'work-in-progress' checkpoint initially):: +After having written some code for ticket #42, Alice starts a patch +(this will be kind of like a 'work-in-progress' checkpoint +initially):: $ hg ci -m '[entities] remove magic' @@ -17,22 +18,22 @@ $ hg phase tip 827: draft -See ? Until the day it becomes a "public" changeset, this can be altered -to no end. How ? It happens with an explicit:: +See? Until the day it becomes a "public" changeset, this can be +altered to no end. How? It happens with an explicit:: $ hg phase --public In practice, pushing to a "publishing" repository can also turn draft -changesets into public ones. Older mercurial releases are automatically +changesets into public ones. Older Mercurial releases are automatically "publishing" since they do not have the notion of non-public changesets (or mutable history). During the transition from older mercurial servers to new ones, this will happen often, so be careful. -Now let's come back to our patch. Next hour sees good progress and W. +Now let's come back to our patch. Next hour sees good progress and Alice wants to complete the patch with the recent stuff (all that's shown by -an "hg diff") to share with a co-worker (let's call him C.W.):: +an "hg diff") to share with a co-worker, Bob:: $ hg amend -m '[entities] fix frobulator (closes #42)' @@ -40,17 +41,17 @@ is just like "hg qrefresh -m"). Before leaving, let's push to the central shared repository. That will -give C.W. the signal that something is ripe for review / further amendments:: +give Bob the signal that something is ripe for review / further amendments:: $ hg push # was done with a modern mercurial, draft phase is preserved -The next day, Mr C.W., who arrives very early, can immediately -work out some glitches in the patch. +The next day, Bob, who arrives very early, can immediately work out +some glitches in the patch. -He then starts two other, for ticket #43 and #44 and finally commits them. +He then starts two others, for ticket #43 and #44 and finally commits them. Then, as original worker arrives, he pushes his stuff. -M W., now equipped with enough properly sugared coffee to survive the +Alice, now equipped with enough properly sugared coffee to survive the next two hours:: $ hg pull @@ -59,21 +60,21 @@ $ hg up "tip ~ 2" -brings him to yesterday's patch. Indeed the patch serial number has +brings her to yesterday's patch. Indeed the patch serial number has increased (827 still exists but has been obsoleted). -He understands that his original patch has been altered. But how did it -evolve ? +She understands that his original patch has been altered. But how did it +evolve? The enhanced hgview shows the two patches. By default only the most recent version of a patch is shown. -Now, when W. installed the mutable-history extensions, he got an alias -that allows him to see the diff between two amendments, defined like this:: +Now, when Alice installed the mutable-history extensions, she got an alias +that allows her to see the diff between two amendments, defined like this:: odiff=diff --rev 'limit(obsparents(.),1)' --rev . -He can see exactly how C.W. amended his work. +She can see exactly how Bob amended her work. * odiff @@ -81,7 +82,7 @@ Amend ... Stabilize -------------------- -Almost perfect ! W. just needs to fix a half dozen grammar oddities in +Almost perfect ! Alice just needs to fix a half dozen grammar oddities in the new docstrings and it will be publishable. Then, another round of: @@ -94,28 +95,28 @@ * the next version, containing grammar fixes, -* the two stacked changesets for tickets #43 .. 44 committed by C.W. +* the two stacked changesets for tickets #43 .. 44 committed by Bob. Indeed, since this changeset still has non-obsolete descendant changesets it cannot be hidden. This branch (old version of #42 and the two descendants by C.W.) is said to be _unstable_. -Why would one want such a state ? Why not auto-stabilize each time "hg -amend" is spelt ? +Why would one want such a state? Why not auto-stabilize each time "hg +amend" is typed out? -W. for one, wouldn't want to merge each time he amends something that -might conflict with the descendant changesets; remember he is -currently updating the very middle of an history ! +Alice for one, wouldn't want to merge each time she amends something that +might conflict with the descendant changesets. Remember she is +currently updating the very middle of an history! -Being now done with grammar and typo fixes, W. decides it is time to -stabilize again the tree. He:: +Being now done with grammar and typo fixes, Alice decides it is time to +stabilize again the tree. She does:: $ hg stabilize two times, one for each unstable descendant. The last time, hgview -shows him a straight line again. Wow ! that feels a bit like a +shows her a straight line again. Wow! that feels a bit like a well-planned surgical operation. At the end, the patient tree has -been properly sewed and any conflict properly handled. +been properly trimmed and any conflict properly handled. Of course nothing fancy really happened: each "stablilize" can be understood in terms of a rebase of the next unstable descendant to the @@ -123,10 +124,10 @@ resolution intermission ...). Except that rebase is a destructive (it removes information from the -repository), unexchangeable operation, and the "evolve + obsolete" +repository), unrecoverable operation, and the "evolve + obsolete" combo, using changeset copy and obsolescence marker, provide evolution semantics by only adding new information to the repository (but more on that later). -He pushes again. +She pushes again.
--- a/docs/evolve-faq.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/evolve-faq.rst Sun Jul 15 14:51:52 2012 +0200 @@ -68,12 +68,12 @@ abusive. But this was very convenient for experimental purposes. This will likely change in non experimental release. -Delete a changeset: ``kill`` +Delete a changeset: ``prune`` ------------------------------------------------------------ -A new ``kill`` command allows removing a changeset. +A new ``prune`` command allows removing a changeset. -Just use ``hg kill <some-rev>``. +Just use ``hg prune <some-rev>``. Moving within the history: ``up`` ``gdown`` and ``gup`` ------------------------------------------------------------ @@ -114,8 +114,8 @@ To split on file boundaries, just use ``uncommit`` command. -There is no official command yet to split at a finer granularity. One -way to achieve this is:: +If you need fine-grained split, there is no official command for that yet. +However, it is easily achieved by manual operation:: ### you want to split changeset A: 42 # update to A parent @@ -128,7 +128,7 @@ $ hg commit # informs mercurial of what appened # current changeset (.) and previous one (.^) replace A (42) - $ hg kill --new . --new .^ 42 + $ hg prune --new . --new .^ 42 Update my current work in progess after a pull @@ -175,19 +175,19 @@ XXX details issue here -Fix my history afterward: ``kill -n`` +Fix my history afterward: ``prune -n`` ------------------------------------------------------------ Sometimes you need to create an obsolete marker by hand. This may happen when upstream has applied some of your patches for example. -you can use ``hg kill --new <new-changeset> <old-changeset>`` to add obsolete +you can use ``hg prune --new <new-changeset> <old-changeset>`` to add obsolete marker. Export to mq: ``synchronize`` ------------------------------------------------------------ -Another extension lets you export your changes to mq. +Another extension allows to export your changes to mq. View diff from the last amend ------------------------------------------------------------
--- a/docs/evolve-good-practice.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/evolve-good-practice.rst Sun Jul 15 14:51:52 2012 +0200 @@ -2,10 +2,10 @@ Good pratice for (early) user of evolve ----------------------------------------- -Avoid instability +Avoid unstability -------------------------------- -The less instability you have the less you need to resolve. +The less unstability you have the less you need to resolve. Evolve is not yet able to detect and solve every situation. And your mind is not ready neither. @@ -13,17 +13,18 @@ Branch as much as possible -------------------------------- -This is not MQ you are not constrainted to linear history. +This is not MQ, you are not constrainted to linear history. -Making a branch per independent branch will help you avoiding instability and conflict. +Making a branch per independent branch will help you avoid unstability +and conflict. Rewrite you change only ------------------------------------------------ -There is no descent conflict detection and handling right now. rewriting other -people changeset garantee that you will get conflict. Communicate with you -fellow developer before trying to touch other people part. (which is a good -pratice in any case) +There is no descent conflict detection and handling right now. +Rewriting other people's changesets guarantees that you will get +conflicts. Communicate with your fellow developers before trying to +touch other people's work (which is a good pratice in any case). Using multiple branch will help you to achieve this goal. @@ -31,13 +32,13 @@ ------------------------------------------------------------------ -If you have children changeset from other people that you don't really care -about, prefer not altering them that risking a conflict by stabilizing them. +If you have children changesets from other people that you don't really care +about, prefer not altering them to risking a conflict by stabilizing them. Do not get too confident --------------------------- -This is an experimental extension and a complexe concept. This is beautiful, -powerful and robust on paper. But the tool and your mind may not be prepared to -all situation yet. +This is an experimental extension and a complex concept. This is beautiful, +powerful and robust on paper, but the tool and your mind may not be prepared for +all situations yet.
--- a/docs/from-mq.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/from-mq.rst Sun Jul 15 14:51:52 2012 +0200 @@ -13,7 +13,7 @@ qrefresh ``amend`` qpop ``update`` or ``qdown`` qpush ``update`` or ``gup`` sometimes ``stabilize`` -qrm ``kill`` +qrm ``prune`̀` qfold ``amend -c`` (for now, ``collapse`` soon) qdiff ``odiff`` @@ -28,11 +28,11 @@ hg qseries ``````````` -All your work in progress is now in real changeset all the time. +All your work in progress is now in real changesets all the time. -You can use the standard log to display them. You can use the phase revset to -display unfinished business only and templates to have the same kind of compact -output qseries has. +You can use the standard log command to display them. You can use the +phase revset to display unfinished work only, and use templates to have +the same kind of compact that the output of qseries has. This will result in something like that:: @@ -48,8 +48,8 @@ $ hg commit -If you want to keep the "wip are not pushed" behavior, you are looking for -setting your changeset in the secret phase using the phase command. +If you want to keep the "WIP is not pushed" behavior, you want to +set your changeset in the secret phase using the phase command. Note that you only need it for the first commit you want to be secret. Later commits will inherit their parents phase. @@ -64,16 +64,15 @@ ```````` A new command from evolution will allow you to rewrite the changeset you are -currently on. just call: +currently on. Just call: $ hg amend - This command takes the same options as commit, plus the switch '-e' (--edit) to edit the commit message in an editor. -Amend have also a -c switch which allow you to make an explicit amending -commit before rewriting a changeset.:: +The amend command also has a -c switch which allow you to make an +explicit amending commit before rewriting a changeset.:: $ hg record -m 'feature A' # oups, I forget some stuff @@ -93,11 +92,11 @@ hg qpop ````````` -the following command emule the behavior of hg qpop: +The following command emulate the behavior of hg qpop: $ hg gdown -If you need to go back to an arbitrary commit you can just us: +If you need to go back to an arbitrary commit you can use: $ hg update @@ -111,7 +110,8 @@ "out of sync". You need to rewrite them on top of the new version of their ancestor. -The evolution extension adds a command to rewrite the "out of sync" changesets::: +The evolution extension adds a command to rewrite the "out of sync" +changesets::: $ hg stabilize @@ -123,7 +123,7 @@ $ hg rebase -r <revset for old version> -d . -note: using graft allow you to pick the changeset you want next as the --move +note: using graft allows you to pick the changeset you want next as the --move option of qpush do. @@ -132,7 +132,7 @@ evolution introduce a new command to mark a changeset as "not wanted anymore".:: - $ hg kill <revset> + $ hg prune <revset> hg qfold ````````` @@ -160,8 +160,8 @@ hg qfinish and hg qimport ```````````````````````````` -Is not necessary anymore. If you want to control exchange and mutability of -changesets, see the phase feature +These are not necessary anymore. If you want to control exchange and +mutability of changesets, see the phase feature
--- a/docs/glossary.rst Fri Jul 13 13:07:42 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ ------------------------------------------------------ -Vocabulary ------------------------------------------------------ - -.. note:: all terminology is subject to change - -:obsolete marker: - express a relation from 0..n new changesets to 1 old changeset -:obsolete changesets: - non public changeset which are target of a obsolete marker - -:unstable changeset: - changeset not obsolete but with obsolete ancestor - -:extinct changeset: - obsolete changeset without unstable descendant - -:suspended changeset: - obsolete changeset with unstable descendant - -:obsolete-parents: - previous versions of a changeset, through a direct obsolete marker. - -:obsolete-children: - new versions of a changeset, through a direct obsolete marker. - -:obsolete-ancestors: - previous versions of a changeset, through any number of obsolete marker - -:obsolete-descendant: - new versions of a changeset, through any number of obsolete marker - -:obsolete-diff: - diff between a changeset and it's obsolete parent - -:obsolete-tip: - obsolete-descendants which are not obsolete themselves. - -:conflicting changeset: - multiple obsolete-tip for an obsolete changeset through diverging obsolete - markers (no changeset split marker)
--- a/docs/index.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/index.rst Sun Jul 15 14:51:52 2012 +0200 @@ -3,7 +3,7 @@ ======================================== -Here are various Materials on planned improvement to mercurial regarding +Here are various materials on planned improvement to Mercurial regarding rewriting history. First read about what challenge arise while rewriting history and how we plan to @@ -14,13 +14,13 @@ instability -The effort is splits in two parts: +The effort is split in two parts: - * The **obsolete marker** concept aims to provide and alternative to ``strip`` + * The **obsolete marker** concept aims to provide an alternative to ``strip`` to get rid of changesets. - * The **evolve** mercurial extension to rewrite history using *obsolete marker* - under the hood. + * The **evolve** mercurial extension rewrites history using obsolete + *marker* under the hood. The first and most important step is by far the **obsolete marker**. However most users will never be directly exposed to the concept. For this reason @@ -77,11 +77,11 @@ You will probably want to use the associated version of hgview (qt viewer recommended). :: - $ hg clone http://hg-lab.logilab.org/wip/hgview/ + $ hg clone http://hg-lab.logilab.org/wip/hgview/ -u obsolete $ cd hgview $ python setup.py install --user -works with mercurial 2.1 and 2.2 (recommended) +Works with mercurial 2.2 --- @@ -126,70 +126,41 @@ :maxdepth: 1 obs-concept + obs-terms obs-implementation obs-road-map -Known caveats -============= - -Here is a list of known issues that will be fixed later: - -* Unstable changeset turn secret. - -* ``hg stabilize`` does not handle conflicts. - Known limitation and bug ================================= Here is a list of know issue that will be fixed later: - * ``hg stabilize`` does not handle merge conflict. You must fallback to graft or rebase when that happen. -* rewriting conflict are not detected yet``hg stabilize`` does not handle them. +* rewriting conflict are not detected yet``hg stabilize`` does not + handle them. * ``hg update`` can move an obsolete parent -* you need to provide to `graft --continue -O` if you started you graft using `-O`. +* you need to provide to `graft --continue -O` if you started you + graft using `-O`. * ``hg merge`` considers an extinct head to be a valid target, hence requiring you to manually specify target all the time. -* trying to exchange obsolete relations with a static http repo will crash. +* trying to exchange obsolete marker with a static http repo will crash. -* Extinct changeset are turned secret by various commands. +* trying to exchange a lot of obsolete markers through http crash. + +* Extinct changesets are turned secret by various commands. * Extinct changesets are hidden using the *hidden* feature of mercurial only supported by a few commands. - Only ``hg log``, ``hgview`` and `hg glog` (2.2 only) support it. ``hg head`` or other visual viewer don't. + Only ``hg log``, ``hgview`` and `hg glog` support it. ``hg head`` or other visual viewer don't. * hg heads show extinct changeset - -Fixed in 2.2 ---------------------------------- - -* hg graphlog show extinct changeset - -* Mercurial 2.1 think you are pushing additional heads even when the new head - obsolete another one. You have to use hg push -f more often than necessary. - - -* ``hg heads`` shows extinct changeset - -* ``hg merge`` considers an extinct head to be a valid target, hence requiring - you to manually specify target all the time. - -* trying to exchange obsolete relations with a static http repo will crash. - -Annexe -====== - -.. toctree:: - :maxdepth: 1 - - glossary
--- a/docs/instability.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/instability.rst Sun Jul 15 14:51:52 2012 +0200 @@ -10,15 +10,14 @@ XXX starts by talking about getting ride of changeset. -DVCS bring two new major concepts to the Version Control Scene: +DVCSes 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*: +To achieve a robust history, three key elements are gathered in *changesets*: * Full snapshot of the versioned content, * Reference to the previous full snapshot used to build the new one, @@ -27,9 +26,9 @@ 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. +This is a very useful property because Changing B parent means +changing B content too. This requires the creation of **another** +changeset, which is semantically good. :: @@ -39,21 +38,22 @@ 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. +But rewriting a changeset with children does not change these +children's parent! And because children of the rewritten changeset +still **depend** on the older "dead" version of the changeset with +can not get rid 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. +I'm calling these children **unstable** because they are based on a +dead changeset and prevent people to get rid 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.. +coexistence of the old and new version of a rewritten changeset. Everybody is working around the issue @@ -67,19 +67,19 @@ 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. +The simplest way to avoid instability is to ensure rewriting +operations always end in a stable situation. This is achieved by +rewriting all affected changesets at the same time. -Rewriting all descendants at the same time than the rewritted of a changeset. +Rewriting all descendants at the same time when rewriting 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. +Several Mercurial commands apply it: rebase, collapse, histedit. +Mercurial also refuses to amend changeset with descendant. The git +branch design enforces such approach in git too. However, DVCS are **Distributed**. This means that you do not control what @@ -91,23 +91,25 @@ 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. +To work around the issue above, Mercurial introduced phases, which +prevent you from rewriting shared changesets and ensure others can't +pull certain changesets from you. But this is a very frustrating +limitation that prevents you to efficiently sharing, reviewing and +collaborating on mutable changesets. -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. +In the Git world, they 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. +The other approach 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: @@ -119,24 +121,24 @@ :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. +It is possible to collaborate over versioned mq! But you are going to +have 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. +Ignore conflicts +``````````````````````````````````` + +Another ignored issue is a conflicting rewrite of the same changeset. +If a changeset is rewritten two times we have two newer versions, +and duplicated history is complicated to merge. + +Mercurial work around by + +The "One set of mutable changset == One developer" mantra is also a way to work +around conflicting rewriting 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 equivalent +of "common ftp" source management for changesets. Facing The Danger Once And For All ------------------------------------------------ @@ -148,13 +150,14 @@ 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: +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. +* 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. @@ -186,7 +189,7 @@ outgoing unstable changesets (use "hg stabilize" or force the push) -And should not not encourage people to create unstability +And should not not encourage people to create instability :: @@ -205,14 +208,14 @@ * Help to automatically solve instability. -* "kill" changeset remotely. +* "prune" 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. + with instability and obsolete marker offer all the tool to safely create and + handle instability locally.
--- a/docs/obs-concept.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/obs-concept.rst Sun Jul 15 14:51:52 2012 +0200 @@ -2,9 +2,10 @@ Why Do We Need a New Concept ----------------------------------------------------------- -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. +Current DVCSes are great tools for forging a series of flawless +changesets 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 a new version of a changeset they actually create a new changeset and get rid of the original changeset. Difficulties to @@ -18,14 +19,14 @@ 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. +repository looks as if the changeset never existed. This approach is simple and effective except for one 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! +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 exist along side the new one [#]_. @@ -40,7 +41,9 @@ interaction with the outer world, which is very unfortunate for a *Distributed* VCS. -.. [#] various work around exists but they require their own workflows which are distinct from the very elegant basic workflow of Mercurial. +.. [#] various work around exists but they require their own workflows + which are distinct from the very elegant basic workflow of + Mercurial. Git Approach: Overwrite Reference ----------------------------------------------------- @@ -68,20 +71,21 @@ This approach goes a bit further but still has a major drawback: -Because you **overwrite** the git-branch, you have no conflict resolution. The last -to act wins. This makes collaboration on multiple changesets difficult because -you can't merge concurrent updates on a changeset. +Because you **overwrite** the git-branch, you have no conflict +resolution. The last to act wins. This makes collaboration on multiple +changesets difficult because you can't merge concurrent updates on a +changeset. -Every overwrite is a forced operation where the operator says "Yes I want this to -replace that. In highly distributed environments, a user may end up with conflicting -references and no proper way to choose. +Every overwrite is a forced operation where the operator says, "yes I +want this to replace that". In highly distributed environments, a user +may end up with conflicting references and no proper way to choose. Because of this way to visualize a repository, git-branches are a core part of git, which makes the user interface more complicated and constrains moving through history. -Finally, even if all older changesets still exist in the repository, accesing them -is still painful. +Finally, even if all older changesets still exist in the repository, +accesing them is still painful. ----------------------------------------------------- @@ -89,9 +93,9 @@ ----------------------------------------------------- -As None of the concepts was powerful enough to fulfill the need of safely -rewriting history, including easy sharing and collaborating on mutable history, -we needed another one. +As none of the concepts was powerful enough to fulfill the need of +safely rewriting history, including easy sharing and collaboration on +mutable history, we needed another one. Basic concept ----------------------------------------------------- @@ -146,8 +150,9 @@ Basic Usage ----------------------------------------------------- -Obsolete markers create a perpendicular history: **a versioned changeset graph**. This means that offers the same features we have for -versioned files but applied to changeset: +Obsolete markers create a perpendicular history: **a versioned +changeset graph**. This means that offers the same features we have +for versioned files but applied to changeset: First: we can display a **coherent view** of the history graph in which only a single version of your changesets is displayed by the UI. @@ -195,9 +200,9 @@ Rebasing `B` and `C` on `A` (as `B'`, `C'`) - This rebase operation added two obsolete markers from new changesets to old - changesets. These two old changesets are now part of the *obsolete* part of the - history. + This rebase operation added two obsolete markers from new + changesets to old changesets. These two old changesets are now + part of the *obsolete* part of the history. 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 @@ -206,9 +211,9 @@ Unstable changesets ``````````````````` -While exploring the possibilities of the obsolete marker a bit further, you may end up with -*obsolete* changesets which have *non-obsolete* children. There is two common ways to -achieve this: +While exploring the possibilities of the obsolete marker a bit +further, you may end up with *obsolete* changesets which have +*non-obsolete* children. There is two common ways to achieve this: * Pull a changeset based of an old version of a changeset [#]_. @@ -221,17 +226,18 @@ Amend `A` into `A'` leaving `B` behind. - In this situation we can not consider `B` as *obsolete*. But we have all - necessary data to detect `B` as an *unstable* branch of the history because - its parent `A` is *obsolete*. In addition, we have enough data to - automatically resolve this instability: we know that the new version of `B` - parent (`A`) is `A'`, We can deduce that we should rebase `B` on `A'` to get - a stable history again. + In this situation we cannot consider `B` as *obsolete*. But we + have all the necessary data to detect `B` as an *unstable* branch + of the history because its parent `A` is *obsolete*. In addition, + we have enough data to automatically resolve this instability: we + know that the new version of `B` parent (`A`) is `A'`. We can + deduce that we should rebase `B` on `A'` to get a stable history + again. 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. +for them. XXX details on automatic resolution for @@ -266,10 +272,10 @@ `B` is *unstable* as before. -Because nothing outside the obsolete set default on *extinct* changesets, they -can be safely hidden in the UI and even garbage collected. *Suspended* changesets -have to stay visible and available until their unstable descendant are rewritten -into stable version. +Because nothing outside the obsolete set default on *extinct* +changesets, they can be safely hidden in the UI and even garbage +collected. *Suspended* changesets have to stay visible and available +until their unstable descendant are rewritten into stable version. Conflicting rewrites @@ -300,20 +306,21 @@ Reliable history `````````````````````` -Obsolete marker help to smooth rewriting operation process. However they -do not change the fact that **you should only rewrite the mutable part of the -history**. The phase concept enforces this rule by explicitly defining a -public immutable set of changesets. Rewriting operations refuse to work on -public changesets, but there are still some corner cases where previously rewritten changesets -are made public. +Obsolete markers help to smooth rewriting operation process. However +they do not change the fact that **you should only rewrite the mutable +part of the history**. The phase concept enforces this rule by +explicitly defining a public immutable set of changesets. Rewriting +operations refuse to work on public changesets, but there are still +some corner cases where previously rewritten changesets are made +public. Special rules apply for obsolete markers pointing to public changesets: * Public changesets are excluded from the obsolete set (public changesets are never hidden or candidate to garbage collection) -* *newer* version of a public changeset are called **latecomer** and highlighted as - an error case. +* *newer* version of a public changeset are called **latecomer** and + highlighted as an error case. Solving such an error is easy. Because we know what changeset a *latecomer* tries to rewrite, we can easily compute a smaller @@ -343,7 +350,7 @@ - gracefully handling history rewriting conflicts, -- various history rewriting UI’s collaborating with an underlying common API. +- various history rewriting UI's collaborating with an underlying common API. .. list-table:: Comparison on solution [#]_ :header-rows: 1
--- a/docs/obs-implementation.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/obs-implementation.rst Sun Jul 15 14:51:52 2012 +0200 @@ -11,7 +11,8 @@ What data should be contained in a Marker ? ```````````````````````````````````````````````````` -There is two critical data that **must** be stored in an obsolete Marker. +There are two critical pieces of information that **must** be stored +in an obsolete Marker. :object: the old obsoleted changeset @@ -23,21 +24,21 @@ --- -This is probably a good idea to have an unique Identifier, for UI, transfert and +This is probably a good idea to have an unique Identifier, for UI, transfer and access. :id: same as changeset but for marker. -The field below will depends of the way we exchange obsolete marker betwenn -changeset. +The field below will depend on the way we exchange obsolete marker between +changesets. --- -Having audit data will be very usefull. When it get messy you need all the -information you can to understand the situation. +Having audit data will be very useful. When it gets messy you need all the +information available to understand the situation. -I have the felling that we are versionning history. Therefor we will probably -need the same kind of information than when versionning Files. +I have the feeling that we are versioning history. Therefor we will probably +need the same kind of information than when versioning Files. :date: date of the marker creation @@ -45,14 +46,14 @@ To go further: -:description: "Optional reason for the rewrite (generated of added by the user)" +:description: "Optional reason for the rewrite (generated by the user)" -:tool: the automated too that made this +:tool: the automated tool that made this :operation: Kind of rewritting operation that created the marker (delete, - update, split, fold, reordering) To help conflict resolution. + update, split, fold, reordering), to help conflict resolution. -Matt see this a "too complicated". I'll wait for him to meet a very hairy +Matt said this is "too complicated". I'll wait for him to meet a very hairy situation to agree that they are needed. Leaving the door open to any addition data is an option too. @@ -95,8 +96,10 @@ Version with Metadata proposal ............................... -An extra files is used to old metadata (date, user, etc) `.hg/store/obs-extra`:. The format of this -field is undefined yet. This will add the following field at the end of a marker +An extra files is used to old metadata (date, user, etc) `.hg/store/obs-extra`:. + +The format of this field is undefined yet. This will add the following +field at the end of a marker * offset of the metadata in obs-extra (8-Bytes integer) @@ -124,7 +127,7 @@ `````````````````````` The new general delta format allows a very efficient storage of two very similar -changesets. Storing obsolete childrens using general delta takes no more place +changesets. Storing obsolete children using general delta takes no more place than storing the obsolete diff. Reverted file will even we reused. The whole operation will take much less space the strip backup. @@ -132,53 +135,54 @@ Abstraction from history rewriting UI ``````````````````````````````````````````` -How Mercurial handle obsolete marker is independent from who decide to create -them and what actual operation solve error case. Any of the existing history -rewriting UI (rebase, mq, histedit) can lay obsolete marker and resolve -situation created by other. To go further a hook system of obsolete marker -creation would allow each mechanism to collaborate with other though a standard -and central mechanism. +How Mercurial handles obsolete marker is independent from what decides +to create them and what actual operation solves the error case. Any of +the existing history rewriting UI (rebase, mq, histedit) can lay +obsolete markers and resolve situation created by others. To go +further, a hook system of obsolete marker creation would allow each +mechanism to collaborate with other though a standard and central +mechanism. Obsolete marker storage ``````````````````````````` -Obsolete marker will most likely be stored outside standard history. They are -multiple reasons for that: +The Obsolete marker will most likely be stored outside standard +history. They are multiple reasons for this: - -First, obsolete markers are really perpendicular to standard history there is not -strong reason to include it here other than convenience. +First, obsolete markers are really perpendicular to standard history +there is no strong reason to include it here other than convenience. Second, storing obsolete marker inside standard history means: - * A changeset must be created every time an obsolete relation is added. Very inconvenient for delete operation. * Obsolete marker must be forged at the creation of the new changeset. This - is very inconvenient for split operation. And in general it become + is very inconvenient for split operation. And in general it becomes complicated to fix history afterward in particular when working with older - client. + clients. -Storing obsolete marker outside history have several pro: +Storing obsolete marker outside history have several pros: -* It ease Exchange of obsolete marker without unnecessary obsolete changeset content +* It eases Exchange of obsolete markers without unnecessary obsolete + changeset contents. -* It allow tuning the actual storage and protocol exchange while maintaining - compatibility with older client through the wire (as we do the repository - format) +* It allows tuning the actual storage and protocol exchange while maintaining + compatibility with older clients through the wire (as we do the repository + format). -* ease the exchange of obsolete related information during discovery to exchange - obsolete changeset relevant to conflict resolution. Exchanging such - information deserve a dedicated protocol. +* It eases the exchange of obsolete related information during + discovery to exchange obsolete changeset relevant to conflict + resolution. Exchanging such information deserves a dedicated + protocol. Persistent ``````````````````````` *Extinct* changeset and obsolete marker will most likely be garbage collected as some point. However, archive server may decide to keep them forever in order to -keep a fully auditable history in it's finest conception. +keep a fully auditable history in its finest conception. Current status @@ -197,12 +201,13 @@ * hidden extinct changesets for UI. -* Use secret phase to remove from discovery obsolete and unstable changeset (to +* Use secret phase to remove from discovery obsolete and unstable changesets (to be improved soon) -* alter rebase to use obsolete marker instead of stripping. +* alter rebase to use obsolete markers instead of stripping. * Have an experimental mq-like extension to rewrite history (more on that later) -* Have an extension to update and mq repository according evolution of standard (more on that later) +* Have an extension to update and mq repository according evolution of + standard (more on that later)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/obs-terms.rst Sun Jul 15 14:51:52 2012 +0200 @@ -0,0 +1,253 @@ +----------------------------------------------------------- +Terminology of the obsolete concept +----------------------------------------------------------- + +Obsolete marker them self +--------------------------------- + +The mutable concept is based on the creation of **obsolete marker**. An obsolete +marker register a relation between the old obsoleted changeset and its newer +version. + +The old changesets is called **precursors**. Its newer version are called +*successors*. A marker always register a single *precursors* but can refer +to: + +- No *successors* at all if the *precursors* if just discarded. +- One *successor* at all if the *precursors* have been rewritten +- Multiple *successors* if the *precursors* have been splitted in myltiple + changeset. + +The **precursors** and **successors** terms can be used on changeset directy: + +:precursors: of a changeset `A` are changesets used as *precursors* by + obsolete marker using changeset `A` as *successors* + +:successors: of a changeset `B` are changesets used as *successors* by + obsolete marker using changeset `B` as *precursors* + +*Precursors* and *successors* directly related within the same marker are called +**direct precursors** and **direct successors** in ambiguous situation. + +The set of all *obsolete markers* create a direct acyclic graph the same way +standard *parent* and *children* relation do. In this graph we have: + +:any precursors: of a `A` are transitive precursors of `A`. (*direct + precursors* of `A` and *precursors* of *precursors*) + +:any successors: of a `A` are transitive successors of `A`. (*direct + successors* of `A` and *precursors* of *precursors*) + +Obsolete markers may revert to changesets that are not known locally. *Direct +precursors* of a changeset may be unknown locally. This is why we usually focus +on the **first known precursors** of changeset + +(The same apply for successors) + +Item in *Any successors* which are not *obsolete* are called **newest +successors** + +.. note:: I'm not very happy with this naming scheme and I'm looking for a + better distinction between direct-successors, any-successors. + +Possible changesets "type" +--------------------------------- + +The following table describe name and behavior of changesets affected by +obsolete marker. Left column describe generic category and right column are +about sub-category. + + ++---------------------+--------------------------+-----------------------------+ +| **mutable** | **obsolete** | **extinct** | +| | | | +| Changeset in either | Obsolete changesets are | Extinct changesets are | +| *draft* or *secret* | mutable changeset used | obsolete one with obsolete | +| phases. | as a precursors. | only descendants. | +| | | | +| | A changeset is used as | They can be safely: | +| | a precursors when at | | +| | least one obsolete | - hidden in the UI, | +| | refer to it in the | - silently excluded from pp | +| | precursors field. | pull and push,t operation | +| | | - ignored by most operation | +| | | - garbage collected. | +| | | | +| | +-----------------------------+ +| | | | +| | | **suspended** | +| | | | +| | | Suspended changesets are | +| | | obsolete one with at least | +| | | one non-obsolete descendant | +| | | | +| | | Thoses descendants prevent | +| | | properties of extincts | +| | | changesets to apply. But | +| | | they will refuse to be | +| | | pushed without --force. | +| | | | +| +--------------------------+-----------------------------+ +| | | | +| | **troublesome** | **unstable** | +| | | | +| | Troublesome commit have | Unstable changesets are | +| | unresolved issue caused | changesets with obsolete | +| | by obsolete relations. | ancestors. | +| | | | +| | Possible issues are | They must be rebased on a | +| | listed in the next | better base to solve the | +| | column. It is possible | situation. | +| | for troublesome | | +| | changeset to combine | (possible alternative name: | +| | multiple issue at once. | precarious) | +| | (eg: conflicting and | | +| | unstable) +-----------------------------+ +| | | | +| | (possible alternative | **latecomer** | +| | name: unsettled, | | +| | troubled) | Latecomer changesets are | +| | | changesets that try to | +| | | be successors of public | +| | | changesets. | +| | | | +| | | Public changeset can't | +| | | be obsolete. Latecomer | +| | | changeset need to be | +| | | rewritten as an overlay | +| | | to this public changeset. | +| | | | +| | | (possible alternative names | +| | | mislead, naive, unaware, | +| | | mindless, disenchanting) | +| | | | +| | +-----------------------------+ +| | | **conflicting** | +| | | | +| | | Conflicting changesets | +| | | happen when multiple | +| | | changesets are successors | +| | | of the same obsolete | +| | | changeset. | +| | | | +| | | Conflicting changesets are | +| | | resolve through a three | +| | | ways merging between the | +| | | two conflicting changesets, | +| | | using the last "obsolete- | +| | | -common-ancestor" as the | +| | | base. | +| | | | +| | | (Changeset splitting is | +| | | properly not detected as a | +| | | conflict) | +| | | | +| +--------------------------+-----------------------------+ +| | | +| | Mutable changesets which are neither *obsolete* or | +| | *troublesome* are *"ok"*. | +| | | +| | Do we really need a name for it ? *"ok"* is a pretty | +| | crappy name :-/ other possibilities are: | +| | | +| | - stable (confusing with stable branch) | +| | - sane | +| | - healthy | +| | | ++---------------------+--------------------------------------------------------+ +| | +| **immutable** | +| | +| Changesets in the *public* phases. | +| | +| Rewriting operation refuse to work on immutable changeset. | +| | +| Obsolete markers that refer an immutable changeset as precursors have | +| no effect on the precussors changeset (but may have effect on the | +| successors) | +| | +| When a mutable changeset becomes immutable its is just *immutable* and loose | +| any property of it's former state. | +| | +| By phase property, once a changeset becomes a public immutable changeset, | +| you can expect it to remain as such forever. | +| | ++------------------------------------------------------------------------------+ + +.. note:: I'm not very happy with the naming of: + + - "ok" changeset + - latecomer + - troublesome + + Any better idea are welcome. + + +Command and operation name +--------------------------------- + + +Existing terms +`````````````` + +Mercurial already use the following terms: + +:amend: rewrite a changeset +:graft: copy a changeset +:rebase: move a changeset + + +Uncommit +````````````` + +remove files from a commit (and leave them as dirty in the working directory) + +The evolve extension have an `uncommit` command that aims to replace most +`rollback` usage. + +Fold +`````````` + +Collapse multiple changeset into one + +The evolve extensions *will* have a `fold` commands + +Prune +`````````` + +Make a changeset obsolete without successors. + +This an important operation as it should replace strip in 95% of the case. + +alternative name: + +- kill: nice name for effect when you forget the "hg" in front on "hg kill". +- obsolete: too vague, long and generic. + +Stabilize +``````````````` + +Automatically resolve troublesome changesets +(unstable, latecomer and conflicting) + +This is an important name as hg pull/pussh will suggest it the same way it +suggest merging when you add heads. + +I do not like stabilize much. + +alternative name: + +- solve (too generic ?) +- evolve (too vague) + + + + + +.. note:: I'm not very happy with the naming of: + + - "ok" changeset + - latecomer + - troublesome + + Any better idea are welcome.
--- a/docs/qsync.rst Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/qsync.rst Sun Jul 15 14:51:52 2012 +0200 @@ -3,8 +3,8 @@ --------------------------------------------------------------------- -People may have tools or co-worker that export to receive mutable history using -versionned mq repository. +People may have tools or co-workers that export to receive mutable history using +a versioned mq repository. For this purpose you can use the ``qsync`` extension:
--- a/docs/tutorials/tutorial.t Fri Jul 13 13:07:42 2012 +0200 +++ b/docs/tutorials/tutorial.t Sun Jul 15 14:51:52 2012 +0200 @@ -284,7 +284,7 @@ I have a new commit but I realize that don't want it. (transport shop list does not fit well in my standard shopping list) - $ hg kill . # . is for working directory parent + $ hg prune . # . is for working directory parent 1 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory now at 387187ad9bd9 @@ -672,7 +672,7 @@ $ hg up 437efbcaf700 1 files updated, 0 files merged, 0 files removed, 0 files unresolved -Relocating unstable change after kill +Relocating unstable change after prune ---------------------------------------------- The remote guy keep working @@ -709,9 +709,9 @@ o 7e82d3f3c2cb (public): Monthy Python Shopping list -In the mean time I noticed you can't buy animals in a super market and I kill the animal changeset: +In the mean time I noticed you can't buy animals in a super market and I prune the animal changeset: - $ hg kill 437efbcaf700 + $ hg prune 437efbcaf700 1 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory now at ffa278c50818 1 new unstables changesets @@ -741,7 +741,7 @@ $ hg log -r 'unstable()' ae45c0c3092a (draft): SPAM SPAM SPAM -# XXX make kill stabilization works +# XXX make prune stabilization works # $ hg stabilize --any # merging shopping
--- a/enable.sh Fri Jul 13 13:07:42 2012 +0200 +++ b/enable.sh Sun Jul 15 14:51:52 2012 +0200 @@ -3,8 +3,8 @@ here=`python -c "import os; print os.path.realpath('$0')"` repo_root=`dirname "$here"` -if !( hg --version -q | grep -qe 'version 2\.[1-9]' ); then - echo 'You need mercurial 2.1 or later' >&2 +if !( hg --version -q | grep -qe 'version 2\.[2-9]' ); then + echo 'You need mercurial 2.2 or later' >&2 exit 2 fi
--- a/hgext/evolve.py Fri Jul 13 13:07:42 2012 +0200 +++ b/hgext/evolve.py Sun Jul 15 14:51:52 2012 +0200 @@ -219,7 +219,7 @@ cmdtable = {} command = cmdutil.command(cmdtable) -@command('^stabilize|evolve', +@command('^stabilize|evolve|solve', [('n', 'dry-run', False, 'do not perform actions, print what to be done'), ('A', 'any', False, 'stabilize any unstable changeset'),], _('[OPTIONS]...')) @@ -338,7 +338,7 @@ ui.warn(_('Multiple non-obsolete children, explicitly update to one\n')) return 1 -@command('^kill|obsolete|prune', +@command('^prune|obsolete|kill', [('n', 'new', [], _("successor changeset"))], _('[OPTION] REV...')) def kill(ui, repo, *revs, **opts):