docs/tutorial/slides.md
changeset 3376 aad37ffd7d58
child 4615 8406d9b06130
equal deleted inserted replaced
3375:1cb549cd6236 3376:aad37ffd7d58
       
     1 ---
       
     2 title: Changeset Evolution training
       
     3 author: |
       
     4   <span style="text-transform: none;"><small>Boris Feld<br/><a href="https://octobus.net">octobus.net</a></small></span>
       
     5 ---
       
     6 
       
     7 # Introduction
       
     8 
       
     9 ## Welcome
       
    10 
       
    11 Hello everyone, and welcome to this Changeset Evolution training. During this session, you will learn how to safely rewrite history with Mercurial and Evolve, and how to collaborate together with your colleagues while rewriting the history at the same time.
       
    12 
       
    13 This training is designed to last approximately ¾ hours.
       
    14 
       
    15 You will use this repository during the training: [https://bitbucket.org/octobus/evolve_training_repo](https://bitbucket.org/octobus/evolve_training_repo). Please clone it somewhere relevant.
       
    16 
       
    17 ```bash
       
    18 $ hg clone https://bitbucket.org/octobus/evolve_training_repo
       
    19 $ cd evolve_training_repo
       
    20 ```
       
    21 
       
    22 Copy the provided hgrc to ensure a smooth training experience:
       
    23 
       
    24 ```bash
       
    25 $ cp hgrc .hg/hgrc
       
    26 ```
       
    27 
       
    28 This training support will contains commands you are expected to type and launch. These commands will be in the following format:
       
    29 
       
    30 ```
       
    31 $ COMMAND YOU ARE EXPECTED TO TYPE
       
    32 output you are expecting to see
       
    33 ```
       
    34 
       
    35 ## Preliminary checks
       
    36 
       
    37 #### Mercurial version
       
    38 
       
    39 First let's use the following command to verify which version of Mercurial you are using:
       
    40 
       
    41 ```
       
    42 $ hg --version
       
    43 Mercurial Distributed SCM (version 4.4.2)
       
    44 (see https://mercurial-scm.org for more information)
       
    45 
       
    46 Copyright (C) 2005-2017 Matt Mackall and others
       
    47 This is free software; see the source for copying conditions. There is NO
       
    48 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       
    49 ```
       
    50 
       
    51 You need at least Mercurial version `4.1`. If you don't have a recent enough version, please call your instructor.
       
    52 
       
    53 In order to activate the Evolve extension, add these lines in your user configuration (using the command `hg config --edit`):
       
    54 
       
    55 ```ini
       
    56 [extensions]
       
    57 evolve =
       
    58 topic =
       
    59 ```
       
    60 
       
    61 #### Mercurial extensions
       
    62 
       
    63 Now let's check the version of your extensions. You will need all of these for the training:
       
    64 
       
    65 ```
       
    66 $ hg --version --verbose
       
    67 [...]
       
    68   evolve       external  7.1.0
       
    69   topic        external  0.6.0
       
    70   rebase       internal
       
    71   histedit     internal
       
    72 ```
       
    73 
       
    74 # The Basics
       
    75 
       
    76 <!-- #### What is Changeset Evolution?
       
    77 
       
    78 With core Mercurial, changesets are permanent and history rewriting has been discouraged for a long time. You can
       
    79 commit new changesets to modify your source code, but you cannot
       
    80 modify or remove old changesets.
       
    81 
       
    82 For years, Mercurial has included various commands that allow
       
    83 history modification: ``rebase``, ``histedit``, ``commit --amend`` and so forth.
       
    84 However, there's a catch: until now, Mercurial's various mechanisms for
       
    85 modifying history have been *unsafe* and expensive, in that changesets were
       
    86 destroyed (“stripped”) rather than simply hidden and still easy to recover.
       
    87 
       
    88 Changeset Evolution makes things better by changing the behaviour of most existing
       
    89 history modification commands so they use a safer mechanism (*changeset
       
    90 obsolescence*, covered below) rather than the older, less safe *strip*
       
    91 operation.
       
    92 
       
    93 ``evolve`` is built on infrastructure in core Mercurial:
       
    94 
       
    95   * *Phases* (starting in Mercurial 2.1) allow you to distinguish
       
    96     mutable and immutable changesets.
       
    97 
       
    98   * *Changeset obsolescence* (starting in Mercurial 2.3) is how
       
    99     Mercurial knows how history has been modified, specifically when
       
   100     one changeset replaces another. In the obsolescence model, a
       
   101     changeset is neither removed nor modified, but is instead marked
       
   102     *obsolete* and typically replaced by a *successor*. Obsolete
       
   103     changesets usually become *hidden* as well. Obsolescence is a
       
   104     disabled feature in Mercurial until you start using ``evolve``.
       
   105 
       
   106  XXX More than just than obsolescence in core ? XXX
       
   107 
       
   108  XXX The part below is a bit overselling XXX
       
   109 
       
   110 Some of the things you can do with ``evolve`` are:
       
   111 
       
   112   * Fix a mistake immediately: “Oops! I just committed a changeset
       
   113     with a syntax error—I'll fix that and amend the changeset so no
       
   114     one sees my mistake.” (While this is possible using default
       
   115     features of core Mercurial, Changeset Evolution makes it safer.)
       
   116 
       
   117   * Fix a mistake a little bit later: “Oops! I broke the tests three
       
   118     commits back, but only noticed it now—I'll just update back to the
       
   119     bad changeset, fix my mistake, amend the changeset, and evolve
       
   120     history to update the affected changesets.”
       
   121 
       
   122   * Remove unwanted changes: “I hacked in some debug output two
       
   123     commits back; everything is working now, so I'll just prune that
       
   124     unwanted changeset and evolve history before pushing.”
       
   125 
       
   126   * Share mutable history with yourself: say you do most of your
       
   127     programming work locally, but need to test on a big remote server
       
   128     somewhere before you know everything is good. You can use
       
   129     ``evolve`` to share mutable history between two computers, pushing
       
   130     finely polished changesets to a public repository only after
       
   131     testing on the test server.
       
   132 
       
   133   * Share mutable history for code review: you don't want to publish
       
   134     unreviewed changesets, but you can't block every commit waiting
       
   135     for code review. The solution is to share mutable history with
       
   136     your reviewer, amending each changeset until it passes review.
       
   137 
       
   138   * Explore and audit the rewrite history of a changeset. Since Mercurial is
       
   139     tracking the edits you make to a changeset, you can look at the history of
       
   140     these edits. This is similar to Mercurial tracking the history of file
       
   141     edits, but at the changeset level. -->
       
   142 
       
   143 In this section, we are going to learn how to do basic history rewriting like rewriting a changeset or rebasing.
       
   144 
       
   145 ### Amend
       
   146 
       
   147 The smallest possible history rewriting is rewriting a changeset description message. We often save and close the editor too early, and/or haven't seen a typo.
       
   148 
       
   149 It is very easy to fix a changeset description message, so let's do that. First be sure that you are in your clone of the `evolve_training_repo`. then update to the `typo` branch:
       
   150 
       
   151 ```
       
   152 $ hg update typo
       
   153 ```
       
   154 
       
   155 Check what the current repository looks like:
       
   156 
       
   157 ~~~raw-file
       
   158 output/fix-a-bug-base.log
       
   159 ~~~
       
   160 
       
   161 ~~~graphviz-file
       
   162 graphs/fix-bug-1.dot
       
   163 ~~~
       
   164 
       
   165 We have a root commit and another based on it. Double-check that you are on the right changeset with the `hg summary` command:
       
   166 
       
   167 ~~~raw-file
       
   168 output/fix-a-bug-base-summary.log
       
   169 ~~~
       
   170 
       
   171 The current commit description message seems wrong, `Fx bug`, there is definitely a letter missing. Let's fix this typo with the `hg commit` command.
       
   172 
       
   173 Usually, the `hg commit` is used to create new commit but we can use the ``--amend`` option to instead modify the current commit (see `hg help commit` for more information):
       
   174 
       
   175 ~~~
       
   176 $ hg commit --amend --message "Fix bug"
       
   177 ~~~
       
   178 
       
   179 Let's take a look at the repository now:
       
   180 
       
   181 ~~~raw-file
       
   182 output/amend-after.log
       
   183 ~~~
       
   184 
       
   185 ~~~graphviz-file
       
   186 graphs/fix-bug-2.dot
       
   187 ~~~
       
   188 
       
   189 The logs before and after amending looks pretty similar, we are going to analyze the differences later. Did you catch the differences?
       
   190 
       
   191 ### Rebase
       
   192 
       
   193 <!-- XXX probably needs a sentence about the merge (Why do you want to avoid it) XXX -->
       
   194 
       
   195 Let's try to rebase something now. Let's say that you have a branch named `build/linuxsupport-v2` which was started on another branch named `build/v2`. Everything was fine until `build/v2` grew a new commit, and now you want to rebase `build/linuxsupport-v2` on top of `build/v2` to be up-to-date with other the changes:
       
   196 
       
   197 ```
       
   198 $ hg update build/linuxsupport-v2
       
   199 ```
       
   200 
       
   201 ~~~raw-file
       
   202 output/rebase-before.log
       
   203 ~~~
       
   204 
       
   205 ~~~graphviz-file
       
   206 graphs/rebase-before.dot
       
   207 ~~~
       
   208 
       
   209 <!-- XXX-REVIEW: Explain rebase CLI interface -->
       
   210 
       
   211 Let's rebase our branch on top of `build/v2` with the `hg rebase` command. The `hg rebase` command have many ways to select commits:
       
   212 
       
   213 1. Explicitly select them using "--rev".
       
   214 2. Use "--source" to select a root commit and include all of its descendants.
       
   215 3. Use "--base" to select a commit; rebase will find ancestors and their descendants which are not also ancestors of the destination.
       
   216 4. If you do not specify any of "--rev", "source", or "--base", rebase  will use "--base ." as above.
       
   217 
       
   218 For this first example, we are gonna stays simple and explicitly select the commits we want to rebase with the `--rev` option.
       
   219 
       
   220 The `hg rebase` command also accepts a destination with the ``--dest`` option. And finally, as we are using named branches, don't forget to use the `--keepbranches` or the rebased commits will be on the wrong branch:
       
   221 
       
   222 ~~~raw-file
       
   223 output/rebase.log
       
   224 ~~~
       
   225 
       
   226 Now we have a nice, clean and flat history:
       
   227 
       
   228 ~~~raw-file
       
   229 output/rebase-after.log
       
   230 ~~~
       
   231 
       
   232 ~~~graphviz-file
       
   233 graphs/rebase-after.dot
       
   234 ~~~
       
   235 
       
   236 For more details about how to use the `hg rebase` command, see `hg help rebase`.
       
   237 
       
   238 ### Under the hood
       
   239 
       
   240 What did happened when we just ran the `hg amend` and `hg rebase` commands? What was done exactly to make the whole process work seamlessly?
       
   241 
       
   242 Let's go back to our previous amend example.
       
   243 
       
   244 ##### Amend
       
   245 
       
   246 When we did our amend, the status of the repository was:
       
   247 
       
   248 ~~~raw-file
       
   249 output/behind-the-hood-amend-before-hash-hidden.log
       
   250 ~~~
       
   251 
       
   252 ~~~graphviz-file
       
   253 graphs/fix-bug-1.dot
       
   254 ~~~
       
   255 
       
   256 And after the amend, the repository looked like:
       
   257 
       
   258 ~~~raw-file
       
   259 output/behind-the-hood-amend-after.log
       
   260 ~~~
       
   261 
       
   262 ~~~graphviz-file
       
   263 graphs/fix-bug-2.dot
       
   264 ~~~
       
   265 
       
   266 Do you see what is the difference?
       
   267 
       
   268 The big difference, apart from the fixed changeset message, is the revision hash and revision number. The `Fix bug` revision changed from `d2eb2ac6a5bd` to `708369dc1bfe`. It means that the fixed changeset is a new one. But where did the old changeset go?
       
   269 
       
   270 It didn't actually go very far, as it just became **hidden**. When we rewrite a changeset with the Evolve extension, instead of blindly delete it, we create a new changeset and hide the old one, which is still there, and we can even see it with the `--hidden` option available on most Mercurial commands:
       
   271 
       
   272 ~~~raw-file
       
   273 output/under-the-hood-amend-after-log-hidden.log
       
   274 ~~~
       
   275 
       
   276 Notice the `x` in the log output which shows that a changeset is hidden.
       
   277 
       
   278 In addition to hiding the original changeset, we are also storing additional information which is recording the relation between a changeset, the **precursor** and its **successor**. It basically stores the information that the commit **X** was rewritten into the commit **Y** by the user **U** at the date **D**. This piece of information is stored in something called an **obsolescence marker**. It will be displayed like this:
       
   279 
       
   280 ~~~graphviz-file
       
   281 graphs/fix-bug-3.dot
       
   282 ~~~
       
   283 
       
   284 Here the commit **5d48a444aba7** was rewritten into **708369dc1bfe**. Also please notice the difference of style of the commit **5d48a444aba7**, that's because it have been rewritten.
       
   285 
       
   286 ##### Rebase
       
   287 
       
   288 **Successors** don't need to share anything with their **precursor**. They could have a different description message, user, date or even parents.
       
   289 
       
   290 Let's look at our earlier rebase example. The status before the rebase was:
       
   291 
       
   292 ~~~raw-file
       
   293 output/behind-the-hood-rebase-before-hash-hidden.log
       
   294 ~~~
       
   295 
       
   296 ~~~graphviz-file
       
   297 graphs/rebase-before.dot
       
   298 ~~~
       
   299 
       
   300 And after it was:
       
   301 
       
   302 ~~~raw-file
       
   303 output/behind-the-hood-rebase-after.log
       
   304 ~~~
       
   305 
       
   306 ~~~graphviz-file
       
   307 graphs/rebase-after.dot
       
   308 ~~~
       
   309 
       
   310 Did the same thing happen under the hood?
       
   311 
       
   312 Yes, exactly! The old changesets are still around, and they are just hidden.
       
   313 
       
   314 ~~~raw-file
       
   315 output/rebase-after-hidden.log
       
   316 ~~~
       
   317 
       
   318 And we created three **obsolescence markers**, between each rebased commit and its **successor**:
       
   319 
       
   320 ~~~graphviz-file
       
   321 graphs/rebase-after-hidden.dot
       
   322 ~~~
       
   323 
       
   324 ### Evolution History
       
   325 
       
   326 Mercurial is designed to track the history of files. Evolution goes beyond, and tracks the history of the history of files. It basically tracks the different versions of your commits.
       
   327 
       
   328 As it is a new dimension of history, the classical Mercurial commands are not always the best to visualize this new history.
       
   329 
       
   330 We have seen that we can see the **hidden** changesets with the `--hidden` option on `hg log`:
       
   331 
       
   332 ~~~raw-file
       
   333 output/under-the-hood-amend-after-log-hidden.log
       
   334 ~~~
       
   335 
       
   336 To visualize the **obsolescence history** of a particular changeset, we can use the dedicated command `hg obslog`. The option are quite similar to `hg log` (you can read `hg help obslog` for more information):
       
   337 
       
   338 ~~~raw-file
       
   339 output/under-the-hood-amend-after-obslog.log
       
   340 ~~~
       
   341 
       
   342 We can even print what changed between the two versions with the `--patch` option:
       
   343 
       
   344 ~~~raw-file
       
   345 output/under-the-hood-amend-after-obslog-patch.log
       
   346 ~~~
       
   347 
       
   348 Obslog works both ways, as it can display **precursors** and **successors** with the `--all` option:
       
   349 
       
   350 ```raw-file
       
   351 output/under-the-hood-amend-after-obslog-no-all.log
       
   352 ```
       
   353 
       
   354 ~~~raw-file
       
   355 output/under-the-hood-amend-after-obslog-all.log
       
   356 ~~~
       
   357 
       
   358 ~~~graphviz-file
       
   359 graphs/fix-bug-3.dot
       
   360 ~~~
       
   361 
       
   362 We can also use obslog on the changesets that we rebased earlier:
       
   363 
       
   364 ~~~raw-file
       
   365 output/under-the-hood-rebase-after-obslog.log
       
   366 ~~~
       
   367 
       
   368 Why the `hg obslog` command is only showing two commits while we rebased three of them?
       
   369 
       
   370 ```raw-file
       
   371 output/under-the-hood-rebase-after-obslog-branch.log
       
   372 ```
       
   373 
       
   374 And why the `hg obslog` command show disconnected graphs when asking for the obslog of the whole branch?
       
   375 
       
   376 ~~~graphviz-file
       
   377 graphs/rebase-after-hidden.dot
       
   378 ~~~
       
   379 
       
   380 While these two obsolescence logs look very similar —because they show a similar change—, the two changesets log histories looked quite different.
       
   381 
       
   382 Using the `hg log` command to understand the Evolution history is hard because it is designed for displaying the files history, not the Evolution history. The `hg obslog` has been specially designed for this use-case and is more suited for this use-case.
       
   383 
       
   384 #### TortoiseHG
       
   385 
       
   386 TortoiseHG should be able to display obsolescence history for your repositories.
       
   387 
       
   388 To display all the **hidden** commits, we need to click on the **search icon**, then on the **Show/Hide hidden changesets** at the right of the **filter** check box. It is also possible to provide a *revset* to filter the repository, for example `:6 + ::20` to display only the revisions we have been working with until now:
       
   389 
       
   390 ![](img/thg-obs.png)
       
   391 
       
   392 <!-- #### Deroulement
       
   393 
       
   394 Travail chacun de son côté pour apprendre à utiliser:
       
   395 
       
   396 - Réecriture de changeset
       
   397 - Affichage de l'obsolescence, log, obslog
       
   398 
       
   399 
       
   400 - Vérifier que chacun sait utiliser les commandes de base
       
   401 - Vérifier que chacun sait utiliser les commandes de visu, hg log, hg log -G, thg?
       
   402 => Pas trop longtemps // répartir
       
   403 
       
   404 - Créer un commit
       
   405 - Le amend sans evolve == bundle
       
   406 - Strip?
       
   407 - rebase sans evolve?
       
   408 - Why is it bad? exemple
       
   409 (Peut-etre pas leur faire pratiquer amend sans evolve, ca prends du temps)
       
   410 
       
   411 - With evolve, now
       
   412 - Activate it, check version
       
   413 - Amend with evolve
       
   414 - rebase with evolve
       
   415 
       
   416 - What happened?
       
   417 - View obs-history, hg log, obslog -->
       
   418 
       
   419 
       
   420 # Medium level
       
   421 
       
   422 ## More rewriting commands
       
   423 
       
   424 The `hg amend` and `hg rebase` commands are the foundations for changeset evolution in Mercurial. You could do everything with these, but, luckily for us, the evolve extension provides human-friendly commands for common needs. We are going to see them now:
       
   425 
       
   426 ### Amend
       
   427 
       
   428 The Evolve extension provides its own `hg amend` command, which is similar to the `hg commit --amend` that we used previously, and adds several nice features:
       
   429 
       
   430 - The `-e`/`--edit` option edits the commit message in an editor, which is not opened by default any more.
       
   431 - The user and date can be updated to the current ones with the `-U`/`--current-user` and `-D`/`--current-date` options.
       
   432 - More capabilities for rewriting the changeset.
       
   433 
       
   434 The `hg amend` command accepts either file paths, to add all the modifications on these files in the current changeset, or the `-i`/`--interactive` option to select precisely what to add in it.
       
   435 
       
   436 We are going to use it to rewrite the author of the changeset:
       
   437 
       
   438 ```
       
   439 $ hg update amend-extract
       
   440 ```
       
   441 
       
   442 We have two commits on the **amend-extract** branch:
       
   443 
       
   444 ```raw-file
       
   445 output/amend-extract-before.log
       
   446 ```
       
   447 
       
   448 The user for the **amend-extract** head seems wrong, so let's fix it with the `hg amend` command:
       
   449 
       
   450 ```raw-file
       
   451 output/amend-user.log
       
   452 ```
       
   453 
       
   454 Now let's check that the user has been amended correctly:
       
   455 
       
   456 ```raw-file
       
   457 output/amend-user-after-export.log
       
   458 ```
       
   459 
       
   460 The user is the good one, but the diff looks weird. It seems that both a bad file **and** an incorrect line have slipped in this commit. We need to fix that.
       
   461 
       
   462 There are several solutions here, and we could manually edit the file and amend it. But, luckily for us, the `hg amend` command also has a very helpful option named `--extract` that will help us.
       
   463 
       
   464 ### Amend extract
       
   465 
       
   466 The `hg amend` command is meant to move file modifications from your working directory to the current changeset (which is considered as the parent of working directory). `hg amend` also provides the option `--extract` that can be used to invert the meaning of the command: with this option, `hg amend` will move the file modifications from your current changeset to your working directory.
       
   467 
       
   468 This is often used to remove a file or a line that is not meant to be in the current commit.
       
   469 
       
   470 As usual, we can either pass file paths or use the `-i` option to select which lines to extract.
       
   471 
       
   472 First, let's extract the badfile:
       
   473 
       
   474 ```raw-file
       
   475 output/amend-extract-badfile.log
       
   476 ```
       
   477 
       
   478 Now let's check the status of the changeset and the working directory:
       
   479 
       
   480 ```raw-file
       
   481 output/amend-extract-badfile-after-export.log
       
   482 ```
       
   483 
       
   484 The file is not included in the commit anymore! Did it just vanish? What if you wanted to keep it and, for example, put it in another commit?
       
   485 
       
   486 Don't worry, the extracted files and lines still are in your working directory:
       
   487 
       
   488 ```raw-file
       
   489 output/amend-extract-badfile-after-status.log
       
   490 ```
       
   491 
       
   492 As we are not going to need this file anymore, let's forget it with the `hg revert` command:
       
   493 
       
   494 ```raw-file
       
   495 output/amend-extract-badfile-after-revert.log
       
   496 ```
       
   497 
       
   498 Also don't forget to remove the file:
       
   499 
       
   500 ```bash
       
   501 $ rm badfile
       
   502 ```
       
   503 
       
   504 Ok. Now we still have a line to extract from our commit, so let's use the handy interactive mode of `hg amend --extract` to extract lines:
       
   505 
       
   506 ```raw-file
       
   507 output/amend-extract.log
       
   508 ```
       
   509 
       
   510 Much better! One last thing, as the line that we extracted is still in our working directory, just like when we extracted a file:
       
   511 
       
   512 ```raw-file
       
   513 output/amend-extract-after-status.log
       
   514 ```
       
   515 
       
   516 ```raw-file
       
   517 output/amend-extract-after-diff.log
       
   518 ```
       
   519 
       
   520 Don't forget to revert the change, as we are not going to need it any more:
       
   521 
       
   522 ```raw-file
       
   523 output/amend-extract-after-revert.log
       
   524 ```
       
   525 
       
   526 Now let's take a look at the obsolescence history:
       
   527 
       
   528 ```raw-file
       
   529 output/amend-extract-after-obslog.log
       
   530 ```
       
   531 
       
   532 The obslog is read from bottom to top:
       
   533 
       
   534 - First we rewrite the user,
       
   535 - Then we extracted a whole file,
       
   536 - Then we extracted a line from a file
       
   537 
       
   538 We have made three changes that generated three **successors**.
       
   539 
       
   540 ```graphviz-file
       
   541 graphs/amend-extract-after-hidden.dot
       
   542 ```
       
   543 
       
   544 ### Fold
       
   545 
       
   546 Sometimes we want to group together several consecutive changesets. Evolve has a command for that: `hg fold`. First, let's update to the right branch:
       
   547 
       
   548 ```
       
   549 $ hg update fold
       
   550 ```
       
   551 
       
   552 Three changesets change the same file, and they could be folded together. This would make a cleaner and more linear history, and hide those pesky intermediate changesets:
       
   553 
       
   554 ```raw-file
       
   555 output/fold-before.log
       
   556 ```
       
   557 
       
   558 ```graphviz-file
       
   559 graphs/fold-before.dot
       
   560 ```
       
   561 
       
   562 We all have been in a similar situation. Let's make a nice and clean changeset with fold:
       
   563 
       
   564 ```raw-file
       
   565 output/fold.log
       
   566 ```
       
   567 
       
   568 That was easy!
       
   569 
       
   570 ```raw-file
       
   571 output/fold-after.log
       
   572 ```
       
   573 
       
   574 ```raw-file
       
   575 output/fold-after-hidden.log
       
   576 ```
       
   577 
       
   578 Can you imagine what the graphs will looks like?
       
   579 
       
   580 ```raw-file
       
   581 output/fold-after-hidden-obslog.log
       
   582 ```
       
   583 
       
   584 ```graphviz-file
       
   585 graphs/fold-after-hidden.log
       
   586 ```
       
   587 
       
   588 ### Split
       
   589 
       
   590 Sometimes you want to `fold` changesets together, and sometimes you want to `split` a changeset into several ones, because it is too big.
       
   591 
       
   592 ```
       
   593 $ hg update split
       
   594 ```
       
   595 
       
   596 Evolve also has a command for that, `hg split`:
       
   597 
       
   598 ```raw-file
       
   599 output/split-before.log
       
   600 ```
       
   601 
       
   602 ```graphviz-file
       
   603 graphs/split-before.dot
       
   604 ```
       
   605 
       
   606 Split accepts a list of revisions and will interactively ask you how you want to split them:
       
   607 
       
   608 ```raw-file
       
   609 output/split.log
       
   610 ```
       
   611 
       
   612 Now let's check the state of the repository:
       
   613 
       
   614 ```raw-file
       
   615 output/split-before-after.log
       
   616 ```
       
   617 
       
   618 ```graphviz-file
       
   619 graphs/split-before-after-hidden.dot
       
   620 ```
       
   621 
       
   622 It looks good. What about the obsolescence history?
       
   623 
       
   624 ```raw-file
       
   625 output/split-after-obslog.log
       
   626 ```
       
   627 
       
   628 ```raw-file
       
   629 output/split-after-obslog-all.log
       
   630 ```
       
   631 
       
   632 ### Prune
       
   633 
       
   634 After rewriting and rebasing changesets, the next common use case for history rewriting is removing a changeset.
       
   635 
       
   636 But we can't permanently remove a changeset without leaving a trace. What if other users are working with the changeset that we want to remove?
       
   637 
       
   638 The common solution is to mark the changeset as removed, and simulate the fact that it has been removed.
       
   639 
       
   640 This is why the Evolve extension is offering the `prune` command. Let's try to prune a changeset:
       
   641 
       
   642 ```
       
   643 $ hg update prune
       
   644 ```
       
   645 
       
   646 ```raw-file
       
   647 output/prune-before.log
       
   648 ```
       
   649 
       
   650 ```graphviz-file
       
   651 graphs/prune-before.dot
       
   652 ```
       
   653 
       
   654 `prune` is easy to use, just give it the revisions you want to prune:
       
   655 
       
   656 ```raw-file
       
   657 output/prune.log
       
   658 ```
       
   659 
       
   660 Now the changeset is not visible any more:
       
   661 
       
   662 ```raw-file
       
   663 output/prune-after.log
       
   664 ```
       
   665 
       
   666 But we can still access it with the `--hidden` option:
       
   667 
       
   668 ```raw-file
       
   669 output/prune-after-hidden.log
       
   670 ```
       
   671 
       
   672 The output of `obslog` changes a bit when displaying pruned changesets:
       
   673 
       
   674 ```raw-file
       
   675 output/prune-after-obslog.log
       
   676 ```
       
   677 
       
   678 ```graphviz-file
       
   679 graphs/prune-after-hidden.dot
       
   680 ```
       
   681 
       
   682 ### Histedit
       
   683 
       
   684 The `hg histedit` command is a power-user command. It allows you to edit a linear series of changesets, and applies a combination of operations on them:
       
   685 
       
   686 - 'pick' to [re]order a changeset
       
   687 - 'drop' to omit changeset
       
   688 - 'mess' to reword the changeset commit message
       
   689 - 'fold' to combine it with the preceding changeset (using the later date)
       
   690 - 'roll' like fold, but discarding this commit's description and date
       
   691 - 'edit' to edit this changeset (preserving date)
       
   692 - 'base' to checkout changeset and apply further changesets from there
       
   693 
       
   694 It's similar to the `git rebase -i` command.
       
   695 
       
   696 First, let's update to the right branch:
       
   697 
       
   698 ```
       
   699 $ hg update histedit
       
   700 ```
       
   701 
       
   702 ```raw-file
       
   703 output/histedit-before-log.log
       
   704 ```
       
   705 
       
   706 ```graphviz-file
       
   707 graphs/histedit-before.dot
       
   708 ```
       
   709 
       
   710 When launching the `hg histedit` command, an editor will show up with the following contents:
       
   711 
       
   712 ```raw-file
       
   713 output/histedit-no-edit.log
       
   714 ```
       
   715 
       
   716 Swap the first two lines with your text editor:
       
   717 
       
   718 ```raw-file
       
   719 output/histedit-commands.log
       
   720 ```
       
   721 
       
   722 Save and exit. Histedit will apply your instructions and finish.
       
   723 
       
   724 Let's see the state of the repository:
       
   725 
       
   726 ```raw-file
       
   727 output/histedit-after-log.log
       
   728 ```
       
   729 
       
   730 ```raw-file
       
   731 output/histedit-after-log-hidden.log
       
   732 ```
       
   733 
       
   734 ```graphviz-file
       
   735 graphs/histedit-after-hidden.dot
       
   736 ```
       
   737 
       
   738 <!-- #### Deroulement
       
   739 
       
   740 - prune with evolve
       
   741 
       
   742 - advanced commands
       
   743 - fold
       
   744 - split -->
       
   745 
       
   746 ## Stack
       
   747 
       
   748 ### Stack definition
       
   749 
       
   750 One big problem when working with a DVCS to identify and switch between the different features/bugfixes you are working on.
       
   751 
       
   752 ### Named branches
       
   753 
       
   754 One solution is to use **named branches**. Named branches are a battle-tested, long-supported solution in Mercurial. Basically, a branch name is stored inside each changeset.
       
   755 
       
   756 This solution has several advantages:
       
   757 
       
   758 - It's supported in all recent-ish Mercurial versions.
       
   759 - It's simple to use.
       
   760 - Most tools are supporting it.
       
   761 
       
   762 But it also has several disadvantages:
       
   763 
       
   764 - Branches do not disappear once they are merged. You need to explicitely close them with `hg commit --close-branch`.
       
   765 - Branches are lost when rebasing them without the `--keepbranches` option of the `hg rebase` command.
       
   766 - New branches needs to be explicitly pushed with the `--new-branch` option of the `hg push` command.
       
   767 
       
   768 We will use named branches for this training, but other solutions are possible, like [topics](https://www.mercurial-scm.org/doc/evolution/tutorials/topic-tutorial.html).
       
   769 
       
   770 <!-- #### Topics
       
   771  -->
       
   772 
       
   773 ### Stack
       
   774 
       
   775 The `topic` extension provides a command to show your current stack, no matter how you defined it. Let's try it on some changesets that we rewrote earlier:
       
   776 
       
   777 ```
       
   778 $ hg update typo
       
   779 ```
       
   780 
       
   781 ```raw-file
       
   782 output/stack-typo.log
       
   783 ```
       
   784 
       
   785 The stack output shows three important data:
       
   786 
       
   787 - First, which branch you are working on (a.k.a. the **current** branch).
       
   788 - Then, all the commits that you are currently working on, with the current one highlighted.
       
   789 - Finally, which commit your branch is based on (**b0**).
       
   790 
       
   791 This branch is not very interesting, so let's move to another one.
       
   792 
       
   793 ```
       
   794 $ hg update build/linuxsupport-v2
       
   795 ```
       
   796 
       
   797 ```raw-file
       
   798 output/stack-rebase.log
       
   799 ```
       
   800 
       
   801 This is more interesting, as now we can see all the three changesets grouped together in the same view. The stack view provides a nice and linear view, even if the changesets are not immediate neighbors.
       
   802 
       
   803 ### Stack movement
       
   804 
       
   805 There is an easy way to navigate in your stack, the `hg next` and `hg prev` commands:
       
   806 
       
   807 ```raw-file
       
   808 output/stack-rebase-prev-from-b3.log
       
   809 ```
       
   810 
       
   811 ```raw-file
       
   812 output/stack-rebase-stack-b2.log
       
   813 ```
       
   814 
       
   815 And now for the `hg next` command:
       
   816 
       
   817 ```raw-file
       
   818 output/stack-rebase-next-from-b2.log
       
   819 ```
       
   820 
       
   821 ```raw-file
       
   822 output/stack-rebase.log
       
   823 ```
       
   824 
       
   825 The stack view also displays nice and easy relative ids for these changesets. You can use theses ids in all commands, for example with the `hg export` command:
       
   826 
       
   827 ```raw-file
       
   828 output/stack-rebase-export-b1.log
       
   829 ```
       
   830 
       
   831 Or with the `hg update` command:
       
   832 
       
   833 ```raw-file
       
   834 output/stack-rebase-update-b2.log
       
   835 ```
       
   836 
       
   837 These ids are handy because you don't need to manipulate changeset ids or revision numbers: contrary to the latters, the formers won't be affected by history edition. They only depend on their order in the branch.
       
   838 
       
   839 ```raw-file
       
   840 output/stack-rebase-stack-b2.log
       
   841 ```
       
   842 
       
   843 ### Edit mid-stack
       
   844 
       
   845 Now that we are in the middle of a stack, let's try amending a commit. The current commit message ends with a dot `.`, and we want to remove it:
       
   846 
       
   847 ```raw-file
       
   848 output/stack-rebase-stack-b2.log
       
   849 ```
       
   850 
       
   851 ```raw-file
       
   852 output/edit-mid-stack.log
       
   853 ```
       
   854 
       
   855 The message `1 new orphan changesets` means that, by amending a changeset having a child, this child is now **unstable**, as we can see with the `hg stack` command:
       
   856 
       
   857 ```raw-file
       
   858 output/edit-mid-stack-after-stack.log
       
   859 ```
       
   860 
       
   861 `hg stack` tries to simplify the view for you. We have amended **b2**, and **b3**'s parent is the precursor version of **b2**, so it is not stable any more. It is now **orphan**.
       
   862 
       
   863 For once, let's use log to see in detail in which situation we are:
       
   864 
       
   865 ```raw-file
       
   866 output/edit-mid-stack-after-log.log
       
   867 ```
       
   868 
       
   869 ```graphviz-file
       
   870 graphs/edit-mid-stack-after.dot
       
   871 ```
       
   872 
       
   873 How can we resolve this situation? It is actually very easy, and we are going to see how in the next section.
       
   874 
       
   875 <!-- #### Deroulement
       
   876 
       
   877 Tout seul:
       
   878 
       
   879 - Topic? stack?
       
   880 
       
   881 - Comment définir ce sur quoi on travaille?
       
   882 
       
   883 - Solution possible: named branches
       
   884 - Avantages des branches nommées
       
   885 - Inconvénients des branches nommées
       
   886 
       
   887 - Solution possible: topic
       
   888 - Avantages des topic
       
   889 - Inconvénients des topic
       
   890 - Commands: hg stack, hg topics, hg topics --age, hg topics --verbose
       
   891 (Pas forcément topic, risque de confusion)
       
   892 
       
   893 - Visualiser une stack avec hg stack, hg show stack?
       
   894 - Se déplacer dans une stack avec hg prev/hg next
       
   895 
       
   896 - Editer au milieu d'une stac
       
   897 
       
   898 - Absorb? (Pas sous windows dur à installer) -->
       
   899 
       
   900 ## Basic instabilities + stabilization
       
   901 
       
   902 Instabilities are a normal step when using Evolve-powered workflows. Several tools are provided to fix them smoothly.
       
   903 
       
   904 #### Log
       
   905 
       
   906 First, let's clarify some vocabulary. An **obsolete** changeset is a changeset that has been rewritten. In the current stack, only one commit is `obsolete`:
       
   907 
       
   908 ```raw-file
       
   909 output/basic-stabilize-before-log-obsolete.log
       
   910 ```
       
   911 
       
   912 A changeset can also be **unstable**, meaning that it could be subject to one or more **instabilities**:
       
   913 
       
   914 * **orphan**, a changeset whose an ancestor is **obsolete**.
       
   915 * **content-divergent**, a changeset which has been rewritten in two different versions.
       
   916 * **phase-divergent**, a changeset which has been both rewritten and published.
       
   917 
       
   918 For the moment, we will only see the **orphan** instability. We can display the **instabilities** of a commit with the `{instabilities}` template keyword:
       
   919 
       
   920 ```raw-file
       
   921 output/basic-stabilize-before-log-instabilities.log
       
   922 ```
       
   923 
       
   924 Here we have also one **orphan** commit, which is the child of the **obsolete** commit.
       
   925 
       
   926 #### Evolve --list
       
   927 
       
   928 The `hg evolve` command has a `--list` option which can list all the instabilities of your repository.
       
   929 
       
   930 ```raw-file
       
   931 output/basic-stabilize-before-evolve-list.log
       
   932 ```
       
   933 
       
   934 #### TortoiseHG
       
   935 
       
   936 Tortoise HG also has a nice support for displaying the instabilities of your repository:
       
   937 
       
   938 ![](img/thg-mid-stack.png)
       
   939 
       
   940 If you want to filter to get a better view, you can use the *revset* `branch(build/linuxsupport-v2)`:
       
   941 
       
   942 ![](img/thg-mid-stack-filter.png)
       
   943 
       
   944 #### Stabilization using `hg next --evolve`
       
   945 
       
   946 ```raw-file
       
   947 output/edit-mid-stack-after-stack.log
       
   948 ```
       
   949 
       
   950 In our current situation, a simple solution to solve the instability is to use the `hg next` command with the `--evolve` option. It will update to the next changeset on the stack, and stabilize it if necessary:
       
   951 
       
   952 ```raw-file
       
   953 output/basic-stabilize-next-evolve.log
       
   954 ```
       
   955 
       
   956 Here, it just rebased our old version of `b3` on top of the new version of `b2`.
       
   957 
       
   958 And now `hg stack` shows us a clean view again:
       
   959 
       
   960 ```raw-file
       
   961 output/basic-stabilize-after-stack.log
       
   962 ```
       
   963 
       
   964 That's better!
       
   965 
       
   966 ```graphviz-file
       
   967 graphs/basic-stabilize-after-stack.dot
       
   968 ```
       
   969 
       
   970 <!-- #### hg evolve
       
   971 
       
   972 XXX-REVIEW: Later -->
       
   973 
       
   974 # Advanced
       
   975 
       
   976 ## Moving change from one commit to another
       
   977 
       
   978 Create two commits:
       
   979 
       
   980 - The first one create a new file, add some content in it.
       
   981 - The second one create another file and modify the first file.
       
   982 
       
   983 Now try to move the change on the first file present in the second commit back in the first commit so that the first commit contains all change on the first file and the second change contains all changes on the second file.
       
   984 
       
   985 ## Exchange
       
   986 
       
   987 Coming Soon™
       
   988 
       
   989 <!-- ## Exchange -->
       
   990 
       
   991 <!-- #### Obsolescence History Synchronization
       
   992 
       
   993 XXX Too theoritical (except first sentence maybe) XXX
       
   994 
       
   995 While obsolescence markers are already useful locally, they unlock their true power when they are exchanged. They are the piece of information that are fundamental to achieve the goal of synchronizing repositories state.
       
   996 
       
   997 If two people starts with the same repository and they each make some modifications, once exchanging all their obsolescence marker with their partner; they should have the same repository state.
       
   998 
       
   999 Given a repository state R, if user A creates obs-markers OBSA and user B creates obs-markers OBSB, `R + OBSA + OBSB = R + OBSB + OBSA`.
       
  1000 
       
  1001 This characteristic is the foundation to make people confident with their modification as they know that they will be able to synchronize with someone and have exactly the same state. XXX-REVIEW BOF
       
  1002 
       
  1003 #### When are exchanged obsolescence markers
       
  1004 
       
  1005 Obsolescence markers are exchanges during all usual exchange methods:
       
  1006 
       
  1007 - Obsolescence markers related to pushed heads are pushed during `hg push`.
       
  1008 - Obsolescence markers related to pulled heads are also pulled during `hg pull`.
       
  1009 - Obsolescence markers are included in bundles.
       
  1010 
       
  1011 New obsolescence markers are automatically applied, so after a `pull` some changesets could become obsolete as they have been rewritten by a new changeset you just pulled.
       
  1012 
       
  1013 XXX-REVIEW: Add example?
       
  1014 
       
  1015 The obsolescence markers only apply to draft changesets though.
       
  1016 
       
  1017 ###### Let's exchange obsmarkers
       
  1018 
       
  1019 Let's try to push and pull some obsolescence-markers, first copy your repository somewhere else, for example:
       
  1020 
       
  1021 ```raw-file
       
  1022 output/basic-exchange-clone.log
       
  1023 ```
       
  1024 
       
  1025 #### Phases
       
  1026 
       
  1027 XXX Too theoritical XXX
       
  1028 
       
  1029 There is a dimension that have been overlooked until now. **Phases**. What are phases? Phases is an information about a changeset status, a changeset could be in one phase at any time:
       
  1030 
       
  1031 * **draft**, the default phase a changeset is just after committing it. This phase denotes that the changeset is still a work in progress. It could be rewritten, rebased, splitted, folded or even pruned before it's considered finished. This state allow a changeset to evolve into another version.
       
  1032 * **public**, the phase a changeset is when it's considered finished. The changeset would likely have been reviewed, tested and even released when they are in this state. This state forbids any rewriting on changeset which are public.
       
  1033 * **secret**, this phase is for changesets that should never be shared. It could be local-only modifications for your environment or a way to commit credentials without sharing it outside. This state allow a changeset to be rewritten, like to be rebased on the most up-to-date head for example.
       
  1034 
       
  1035 Phase are about changesets but they are not part of the commit information, meaning that changing the phase of a changeset does not change it's changeset hash.
       
  1036 
       
  1037 These phases are ordered (public < draft < secret) and no changeset can be in
       
  1038 a lower phase than its ancestors. For instance, if a changeset is public, all
       
  1039 its ancestors are also public. Lastly, changeset phases should only be changed
       
  1040 towards the public phase.
       
  1041 
       
  1042 Changeset are created in the **draft** phase by default and move to the **public** phase in several scenarios.
       
  1043 
       
  1044 #### Phase movement
       
  1045 
       
  1046 The original scenario for **phases** is to permits local rewriting of changesets that have not been pushed. You create draft changesets, you test them locally, possibly amend them, rebased them or clean it then you push it to a server and they become **public** at this occasion.
       
  1047 
       
  1048 While this scenario is pretty sensible, not altering shared commit make a lot of problems disappears, move powerful workflows could be unlocked when decoupling the sharing part with the publishing part.
       
  1049 
       
  1050 By default, hg server are in **publishing** mode, meaning that:
       
  1051 
       
  1052 - all draft changesets that are pulled or cloned appear in phase public on the client.
       
  1053 
       
  1054 - all draft changesets that are pushed appear as public on both client and server.
       
  1055 
       
  1056 - secret changesets are neither pushed, pulled, or cloned.
       
  1057 
       
  1058 Hg servers could also be configured into **non-publishing** mode with this configuration:
       
  1059 
       
  1060 ```ini
       
  1061 [phases]
       
  1062 publish = False
       
  1063 ```
       
  1064 
       
  1065 When pushing to a **non-publishing** mode, draft changesets are not longer made **public** anymore, allowing people and teams to share unfinished works. This way, it's still possible to edit a changeset after sharing it, meaning that:
       
  1066 
       
  1067 - a changeset could be updated after it has been reviewed.
       
  1068 - a changeset could be updated after a Continuous Integration tool show that some tests on some platforms are broken.
       
  1069 - a changeset could be updated after a co-worker tried implementing another feature on top of it.
       
  1070 
       
  1071 #### Usual phase workflow
       
  1072 
       
  1073 While sharing unfinished works is powerful, move **draft** changeset to the **public** phase when pushing them to **publishing** server is powerful by its simplicity. Its easy to understand as **non-publishing** servers could be seen as work-in-progress while **publishing** servers is meant for public, finished work that you commit to never alter. XXX-REVIEW Bof
       
  1074 
       
  1075 The usual way of having both advantages is to have both a **non-publishing** server where developers push for sharing work and asking for review and another **non-publishing** server when ready changesets are pushed, marking them as **public**.
       
  1076 
       
  1077 This way the **publishing** repository will only contains **public** changesets while the **non-publishing** one will contains all the **public** changesets plus all the **drafts** changesets.
       
  1078 
       
  1079 #### Phase visualization
       
  1080 
       
  1081 Phase is not shown by default in `hg log`, but we can ask for it with the `{phase}` template:
       
  1082 
       
  1083 ```raw-file
       
  1084 output/split-after-log-phase.log
       
  1085 ```
       
  1086 
       
  1087 It's also possible to use `hg phase` to recover the phase of a revision(s):
       
  1088 
       
  1089 ```raw-file
       
  1090 output/split-after-phase.log
       
  1091 ```
       
  1092 
       
  1093 You might wondered why you saw different forms in the graphs before, that was the phase that were shown. From now on, public changesets will be shown as circles, drafts changesets will be shown as hexagons and secrets changesets will be shown as squares:
       
  1094 
       
  1095 ```graphviz-file
       
  1096 graphs/phases.dot
       
  1097 ```
       
  1098 
       
  1099 #### Phase selection
       
  1100 
       
  1101 Phase have a few revsets for selecting changesets by their phases:
       
  1102 
       
  1103 - `public()`, select all public changesets.
       
  1104 - `draft()`, select all draft changesets.
       
  1105 - `secrets()`, select all secret changesets.
       
  1106 
       
  1107 It could be used to:
       
  1108 
       
  1109 - select all non-public changesets with `hg log -r "not public()"`.
       
  1110 - change all secret changesets to draft with `hg phase --draft "secret()"`. -->
       
  1111 
       
  1112 <!-- #### Deroulement
       
  1113 
       
  1114 Toujours tout seul:
       
  1115 
       
  1116 - push / pull
       
  1117 - phases -->
       
  1118 
       
  1119 <!-- ## Advanced -->
       
  1120 
       
  1121 <!-- #### Deroulement
       
  1122 
       
  1123 Advances use-cases:
       
  1124 
       
  1125 - Move part of a changeset to another (split+fold) -->
       
  1126 
       
  1127 <!-- ## Let's start the fun -->
       
  1128 
       
  1129 <!-- #### Deroulement
       
  1130 
       
  1131 À deux:
       
  1132 
       
  1133 - troubles, divergence, orphan
       
  1134 - troubles visualization
       
  1135 - troubles resolution
       
  1136 - collaboration workflow
       
  1137 
       
  1138 Parler du happy path d'abord -->
       
  1139 
       
  1140 <!-- ## Content to integrate (presentation old content)
       
  1141 
       
  1142 #### Once upon a time
       
  1143 
       
  1144 #### You fix a bug
       
  1145 
       
  1146 (With a small typo)
       
  1147 
       
  1148 ~~~graphviz-file
       
  1149 graphs/fix-bug-1.dot
       
  1150 ~~~
       
  1151 
       
  1152 #### You write more code
       
  1153 
       
  1154 <img src="https://media0.giphy.com/media/13GIgrGdslD9oQ/giphy.gif">
       
  1155 
       
  1156 #### Urgent merge
       
  1157 
       
  1158 <img src="https://media.giphy.com/media/OBnwDJW77acLK/giphy.gif">
       
  1159 
       
  1160 #### Fix the fix
       
  1161 
       
  1162 But it's easy to fix them:
       
  1163 
       
  1164 ~~~ {.sh}
       
  1165 hg commit --amend -m "Fix bug"
       
  1166 ~~~
       
  1167 
       
  1168 ~~~graphviz-file
       
  1169 graphs/fix-bug-2.dot
       
  1170 ~~~
       
  1171 
       
  1172 #### Too fast!
       
  1173 
       
  1174 But wait you had local changes! And they get incorporated into the amend.
       
  1175 
       
  1176 <img src="https://media1.giphy.com/media/vMiCDfoKdJP0c/giphy.gif">
       
  1177 
       
  1178 10 more minutes to unbundle revert the files, relaunch the tests, etc...
       
  1179 
       
  1180 #### With evolve now
       
  1181 
       
  1182 ~~~graphviz-file
       
  1183 graphs/fix-bug-1.dot
       
  1184 ~~~
       
  1185 
       
  1186 #### Same CLI
       
  1187 
       
  1188 With evolve this time:
       
  1189 
       
  1190 ~~~ {.sh}
       
  1191 hg commit --amend -m "Fix bug"
       
  1192 ~~~
       
  1193 
       
  1194 ~~~graphviz-file
       
  1195 graphs/fix-bug-2.dot
       
  1196 ~~~
       
  1197 
       
  1198 #### Ok what the difference?
       
  1199 
       
  1200 #### Before / After
       
  1201 
       
  1202 
       
  1203 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  1204 <div class='left' style='order:1; width: 50%'>
       
  1205 Before:
       
  1206 
       
  1207 </div>
       
  1208 
       
  1209 <div class='right' style='order:2; width: 50%'>
       
  1210 After:
       
  1211 
       
  1212 ~~~raw-file
       
  1213 output/fix-a-bug-with-evolve-1.log
       
  1214 ~~~
       
  1215 
       
  1216 </div>
       
  1217 </div>
       
  1218 
       
  1219 #### Difference is hidden
       
  1220 
       
  1221 
       
  1222 ~~~raw-file
       
  1223 output/fix-a-bug-with-evolve-2.log
       
  1224 ~~~
       
  1225 
       
  1226 The old revision is still there!
       
  1227 
       
  1228 #### Impact
       
  1229 
       
  1230 * Easier to access obsolete changesets
       
  1231     - No more `.hg/strip-backup/` expedition
       
  1232 * Respect the append only model of Mercurial
       
  1233     - No large data movement on edition
       
  1234     - No cache trauma
       
  1235 
       
  1236 #### One more thing
       
  1237 
       
  1238 <img src="https://media.giphy.com/media/F3MoHzSjjJ16w/giphy.gif">
       
  1239 
       
  1240 #### Track evolution
       
  1241 
       
  1242 ~~~graphviz-file
       
  1243 graphs/fix-bug-3.dot
       
  1244 ~~~
       
  1245 ~~~graphviz
       
  1246     digraph G {
       
  1247         rankdir="BT";
       
  1248         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF"];
       
  1249 
       
  1250         // Revisions
       
  1251         node[group=main];
       
  1252         Parent -> "Fix bug";
       
  1253         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  1254         Parent -> "Fx bug";
       
  1255 
       
  1256         // Obsolescence links
       
  1257         edge[dir=back, style=dotted, arrowtail=dot];
       
  1258         "Fx bug" -> "Fix bug";
       
  1259     }
       
  1260 ~~~
       
  1261 
       
  1262 #### Obsmarker
       
  1263 
       
  1264 Stores relation between evolutions
       
  1265 
       
  1266 
       
  1267 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  1268 <div class='left' style='order:1; width: 50%'>
       
  1269 ~~~graphviz
       
  1270     digraph G {
       
  1271         rankdir="BT";
       
  1272         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF"];
       
  1273 
       
  1274         node[group=obsolete, style="dotted, filled" fillcolor="#DFDFFF"];
       
  1275         edge[dir=back, style=dotted, arrowtail=dot];
       
  1276         "Predecessor" -> "Successor";
       
  1277 
       
  1278         "Successor" [style="filled", fillcolor="#7F7FFF"];
       
  1279     }
       
  1280 ~~~
       
  1281 </div>
       
  1282 
       
  1283 <div class='right' style='order:2; width: 50%'>
       
  1284 
       
  1285 * And some metas:
       
  1286     * User
       
  1287     * Date
       
  1288     * And others...
       
  1289 </div>
       
  1290 </div>
       
  1291 
       
  1292 ## Topic
       
  1293 
       
  1294 #### Topic
       
  1295 
       
  1296 <pre>
       
  1297 $> hg topic myfeature
       
  1298 $> hg topics
       
  1299 <span style="color:green;"> * </span><span style="color:green;">myfeature</span>
       
  1300 </pre>
       
  1301 
       
  1302 #### Topic
       
  1303 
       
  1304 Topic branches are lightweight branches which disappear when changes are
       
  1305 finalized (move to the public phase). They can help users to organise and share
       
  1306 their unfinished work.
       
  1307 
       
  1308 #### Topic storage
       
  1309 
       
  1310 Like named-branches, topics are stored on the changeset.
       
  1311 
       
  1312 #### Head definition
       
  1313 
       
  1314 <pre>
       
  1315 $> hg log -G
       
  1316 @  <span style="color:olive;">changeset:   2:03a68957ddd8</span>
       
  1317 |  tag:         tip
       
  1318 |  parent:      0:478309adfd3c
       
  1319 |  user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1320 |  date:        Mon Jul 24 22:39:27 2017 +0200
       
  1321 |  summary:     default
       
  1322 |
       
  1323 | o  <span style="color:olive;">changeset:   1:3d2362d21bb4</span>
       
  1324 |/   <span style="background-color:green;">topic:       myfeature</span>
       
  1325 |    user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1326 |    date:        Mon Jul 24 22:39:55 2017 +0200
       
  1327 |    summary:     myfeature
       
  1328 |
       
  1329 o  <span style="color:olive;">changeset:   0:478309adfd3c</span>
       
  1330    user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1331    date:        Mon Jul 24 16:01:32 2017 +0200
       
  1332    summary:     ROOT
       
  1333 </pre>
       
  1334 
       
  1335 #### Heads
       
  1336 
       
  1337 <pre>
       
  1338 $> hg log -r 'head() and branch(default)'
       
  1339 <span style="color:olive;">changeset:   2:03a68957ddd8</span>
       
  1340 tag:         tip
       
  1341 parent:      0:478309adfd3c
       
  1342 user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1343 date:        Mon Jul 24 22:39:27 2017 +0200
       
  1344 summary:     default
       
  1345 </pre>
       
  1346 
       
  1347 #### Name definition
       
  1348 
       
  1349 We can update to a topic directly:
       
  1350 
       
  1351 <pre>
       
  1352 $> hg update myfeature
       
  1353 switching to topic myfeature
       
  1354 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
       
  1355 </pre>
       
  1356 
       
  1357 #### Pre-rebase
       
  1358 
       
  1359 <pre>
       
  1360 $> hg log -G
       
  1361 o  <span style="color:olive;">changeset:   2:03a68957ddd8</span>
       
  1362 |  tag:         tip
       
  1363 |  parent:      0:478309adfd3c
       
  1364 |  user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1365 |  date:        Mon Jul 24 22:39:27 2017 +0200
       
  1366 |  summary:     default
       
  1367 |
       
  1368 | @  <span style="color:olive;">changeset:   1:3d2362d21bb4</span>
       
  1369 |/   <span style="background-color:green;">topic:       myfeature</span>
       
  1370 |    user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1371 |    date:        Mon Jul 24 22:39:55 2017 +0200
       
  1372 |    summary:     myfeature
       
  1373 |
       
  1374 o  <span style="color:olive;">changeset:   0:478309adfd3c</span>
       
  1375    user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1376    date:        Mon Jul 24 16:01:32 2017 +0200
       
  1377    summary:     ROOT
       
  1378 </pre>
       
  1379 
       
  1380 #### Topic rebase
       
  1381 
       
  1382 Topics can be rebased easily on their base branch
       
  1383 
       
  1384 <pre>
       
  1385 $> hg rebase
       
  1386 rebasing 1:3d2362d21bb4 &quot;myfeature&quot;
       
  1387 switching to topic myfeature
       
  1388 </pre>
       
  1389 
       
  1390 #### Result
       
  1391 
       
  1392 <pre>
       
  1393 $> hg log -G
       
  1394 @  <span style="color:olive;">changeset:   3:0a51e0d4d460</span>
       
  1395 |  tag:         tip
       
  1396 |  <span style="background-color:green;">topic:       myfeature</span>
       
  1397 |  user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1398 |  date:        Mon Jul 24 22:39:55 2017 +0200
       
  1399 |  summary:     myfeature
       
  1400 |
       
  1401 o  <span style="color:olive;">changeset:   2:03a68957ddd8</span>
       
  1402 |  parent:      0:478309adfd3c
       
  1403 |  user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1404 |  date:        Mon Jul 24 22:39:27 2017 +0200
       
  1405 |  summary:     default
       
  1406 |
       
  1407 o  <span style="color:olive;">changeset:   0:478309adfd3c</span>
       
  1408    user:        Boris Feld &lt;boris.feld@octobus.net&gt;
       
  1409    date:        Mon Jul 24 16:01:32 2017 +0200
       
  1410    summary:     ROOT
       
  1411 </pre>
       
  1412 
       
  1413 #### Topic push
       
  1414 
       
  1415 You can push topic without -f if you push only 1 head:
       
  1416 
       
  1417 <pre>
       
  1418 hg push -r myfeature
       
  1419 </pre>
       
  1420 
       
  1421 Even if the topic is not up-to-date to its branch.
       
  1422 
       
  1423 ## Stack Workflow
       
  1424 
       
  1425 #### Stack
       
  1426 
       
  1427 <pre>
       
  1428 $> hg stack
       
  1429 ###### topic: <span style="color:green;">myfeature</span>
       
  1430 ###### branch: feature
       
  1431 <span style="color:teal;">t4</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step4</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1432 <span style="color:olive;">t3</span><span style="color:green;">:</span> Step3
       
  1433 <span style="color:olive;">t2</span><span style="color:green;">:</span> Step2
       
  1434 <span style="color:olive;">t1</span><span style="color:green;">:</span> Step
       
  1435 <span style="color:grey;">t0^ Trunk</span>
       
  1436 </pre>
       
  1437 
       
  1438 #### Why Stack?
       
  1439 
       
  1440 * Feature = multiple steps,
       
  1441 
       
  1442 * Smaller = Simpler
       
  1443 
       
  1444 * Simpler = Earlier merge in trunk
       
  1445 
       
  1446 * Ease experiment with Alternative
       
  1447 
       
  1448 * etc…
       
  1449 
       
  1450 #### Prev
       
  1451 
       
  1452 <pre>
       
  1453 $> hg prev
       
  1454 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
       
  1455 [<span style="color:blue;">7</span>] Step3
       
  1456 $> hg stack
       
  1457 ###### topic: <span style="color:green;">myfeature</span>
       
  1458 ###### branch: feature
       
  1459 <span style="color:olive;">t4</span><span style="color:green;">:</span> Step4
       
  1460 <span style="color:teal;">t3</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step3</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1461 <span style="color:olive;">t2</span><span style="color:green;">:</span> Step2
       
  1462 <span style="color:olive;">t1</span><span style="color:green;">:</span> Step
       
  1463 <span style="color:grey;">t0^ Trunk</span>
       
  1464 </pre>
       
  1465 
       
  1466 #### Next
       
  1467 
       
  1468 <pre>
       
  1469 $> hg next
       
  1470 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
       
  1471 [<span style="color:blue;">8</span>] Step4
       
  1472 $> hg stack
       
  1473 ###### topic: <span style="color:green;">myfeature</span>
       
  1474 ###### branch: feature
       
  1475 <span style="color:teal;">t4</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step4</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1476 <span style="color:olive;">t3</span><span style="color:green;">:</span> Step3
       
  1477 <span style="color:olive;">t2</span><span style="color:green;">:</span> Step2
       
  1478 <span style="color:olive;">t1</span><span style="color:green;">:</span> Step
       
  1479 <span style="color:grey;">t0^ Trunk</span>
       
  1480 </pre>
       
  1481 
       
  1482 #### T\#
       
  1483 
       
  1484 <pre>
       
  1485 $> hg update --rev t2
       
  1486 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
       
  1487 [<span style="color:blue;">8</span>] Step4
       
  1488 $> hg stack
       
  1489 ###### topic: <span style="color:green;">myfeature</span>
       
  1490 ###### branch: feature
       
  1491 <span style="color:olive;">t4</span><span style="color:green;">:</span> Step4
       
  1492 <span style="color:olive;">t3</span><span style="color:green;">:</span> Step3
       
  1493 <span style="color:teal;">t2</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step2</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1494 <span style="color:olive;">t1</span><span style="color:green;">:</span> Step
       
  1495 <span style="color:grey;">t0^ Trunk</span>
       
  1496 </pre>
       
  1497 
       
  1498 #### Editing mid-stack
       
  1499 
       
  1500 <pre>
       
  1501 $> hg update --rev t1
       
  1502 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
       
  1503 $> hg commit --amend -m "Step1"
       
  1504 <span style="color:gold;">3 new unstable changesets</span>
       
  1505 </pre>
       
  1506 
       
  1507 #### What have we done?
       
  1508 
       
  1509 <pre>
       
  1510 $> hg log -G -T compact
       
  1511 @  <span style="color:olive;">9</span>[tip]     1aa1be5ada40    Step1
       
  1512 |
       
  1513 | o  <span style="color:olive;">8</span>        cf90b2de7e65    Step4 <span style="color:red;">(unstable)</span>
       
  1514 | |
       
  1515 | o  <span style="color:olive;">7</span>        e208d4205c8e    Step3 <span style="color:red;">(unstable)</span>
       
  1516 | |
       
  1517 | o  <span style="color:olive;">6</span>        673ff300cf3a    Step2 <span style="color:red;">(unstable)</span>
       
  1518 | |
       
  1519 | <span style="color:grey;">x  5        8bb88a31dd28    Step</span>
       
  1520 |/
       
  1521 o  <span style="color:olive;">4</span>          3294c1730df7    Trunk
       
  1522 ~
       
  1523 </pre>
       
  1524 
       
  1525 #### Stack to the rescue!
       
  1526 
       
  1527 <pre>
       
  1528 $> hg stack
       
  1529 ###### topic: <span style="color:green;">myfeature</span>
       
  1530 ###### branch: feature
       
  1531 <span style="color:olive;">t4</span><span style="color:red;">$</span> Step4<span style="color:red;"> (unstable)</span>
       
  1532 <span style="color:olive;">t3</span><span style="color:red;">$</span> Step3<span style="color:red;"> (unstable)</span>
       
  1533 <span style="color:olive;">t2</span><span style="color:red;">$</span> Step2<span style="color:red;"> (unstable)</span>
       
  1534 <span style="color:teal;">t1</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step1</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1535 <span style="color:grey;">t0^ Trunk</span>
       
  1536 </pre>
       
  1537 
       
  1538 #### Don't panic
       
  1539 
       
  1540 <pre>
       
  1541 $> hg next --evolve
       
  1542 move:[<span style="color:blue;">6</span>] Step2
       
  1543 atop:[<span style="color:blue;">9</span>] Step1
       
  1544 working directory now at <span style="color:olive;">d72473cbf9a6</span>
       
  1545 $> hg stack
       
  1546 ###### topic: <span style="color:green;">myfeature</span>
       
  1547 ###### branch: feature
       
  1548 <span style="color:olive;">t4</span><span style="color:red;">$</span> Step4<span style="color:red;"> (unstable)</span>
       
  1549 <span style="color:olive;">t3</span><span style="color:red;">$</span> Step3<span style="color:red;"> (unstable)</span>
       
  1550 <span style="color:teal;">t2</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step2</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1551 <span style="color:olive;">t1</span><span style="color:green;">:</span> Step1
       
  1552 <span style="color:grey;">t0^ Trunk</span>
       
  1553 </pre>
       
  1554 
       
  1555 #### Go on
       
  1556 
       
  1557 <img src="https://media.giphy.com/media/KBx7fQoLxuV7G/giphy.gif">
       
  1558 
       
  1559 #### Go on
       
  1560 
       
  1561 <pre>
       
  1562 $> hg next --evolve
       
  1563 move:[<span style="color:blue;">7</span>] Step3
       
  1564 atop:[<span style="color:blue;">10</span>] Step2
       
  1565 working directory now at <span style="color:olive;">4062d6ecd214</span>
       
  1566 $> hg stack
       
  1567 ###### topic: <span style="color:green;">myfeature</span>
       
  1568 ###### branch: feature
       
  1569 <span style="color:olive;">t4</span><span style="color:red;">$</span> Step4<span style="color:red;"> (unstable)</span>
       
  1570 <span style="color:teal;">t3</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step3</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1571 <span style="color:olive;">t2</span><span style="color:green;">:</span> Step2
       
  1572 <span style="color:olive;">t1</span><span style="color:green;">:</span> Step1
       
  1573 <span style="color:grey;">t0^ Trunk</span>
       
  1574 </pre>
       
  1575 
       
  1576 #### Go on
       
  1577 
       
  1578 <pre>
       
  1579 $> hg next --evolve
       
  1580 move:[<span style="color:blue;">8</span>] Step4
       
  1581 atop:[<span style="color:blue;">11</span>] Step3
       
  1582 working directory now at <span style="color:olive;">4dcd9dfedf1b</span>
       
  1583 $> hg stack
       
  1584 ###### topic: <span style="color:green;">myfeature</span>
       
  1585 ###### branch: feature
       
  1586 <span style="color:teal;">t4</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step4</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1587 <span style="color:olive;">t3</span><span style="color:green;">:</span> Step3
       
  1588 <span style="color:olive;">t2</span><span style="color:green;">:</span> Step2
       
  1589 <span style="color:olive;">t1</span><span style="color:green;">:</span> Step1
       
  1590 <span style="color:grey;">t0^ Trunk</span>
       
  1591 </pre>
       
  1592 
       
  1593 #### Go on
       
  1594 
       
  1595 <pre>
       
  1596 $> hg next --evolve
       
  1597 no children
       
  1598 </pre>
       
  1599 
       
  1600 #### Better!
       
  1601 
       
  1602 <pre>
       
  1603 $> hg log -G -T compact
       
  1604 @  <span style="color:olive;">12</span>[tip]    4dcd9dfedf1b    Step4
       
  1605 |
       
  1606 o  <span style="color:olive;">11</span>         4062d6ecd214    Step3
       
  1607 |
       
  1608 o  <span style="color:olive;">10</span>         d72473cbf9a6    Step2
       
  1609 |
       
  1610 o  <span style="color:olive;">9</span>          1aa1be5ada40    Step1
       
  1611 |
       
  1612 o  <span style="color:olive;">4</span>          3294c1730df7    Trunk
       
  1613 ~
       
  1614 </pre>
       
  1615 
       
  1616 #### More Rewrite Tools
       
  1617 
       
  1618 <table>
       
  1619 <tr>
       
  1620 <th>Operation</th>
       
  1621 <th>command</th>
       
  1622 </tr>
       
  1623 <tr>
       
  1624 <td>Modify</td>
       
  1625 <td>`hg amend`<br></td>
       
  1626 </tr>
       
  1627 <tr>
       
  1628 <td>Remove</td>
       
  1629 <td>`hg prune`<br></td>
       
  1630 </tr>
       
  1631 <tr>
       
  1632 <td>Move</td>
       
  1633 <td>`hg grab`<br></td>
       
  1634 </tr>
       
  1635 <tr>
       
  1636 <td>Split</td>
       
  1637 <td>`hg split`<br></td>
       
  1638 </tr>
       
  1639 <tr>
       
  1640 <td>Fold</td>
       
  1641 <td>`hg fold`<br></td>
       
  1642 </tr>
       
  1643 </table>
       
  1644 
       
  1645 #### Multi headed stack
       
  1646 
       
  1647 <pre>
       
  1648 $> hg log -G -T compact
       
  1649 @  <span style="color:olive;">6</span>[tip]   189f54192937   Step4.5
       
  1650 |
       
  1651 | o  <span style="color:olive;">5</span>   c1a91e7c74f5   Step5
       
  1652 |/
       
  1653 o  <span style="color:olive;">4</span>   826d2fbb601a   Step4
       
  1654 |
       
  1655 o  <span style="color:olive;">3</span>   08bcdd8d972b   Step3
       
  1656 |
       
  1657 o  <span style="color:olive;">2</span>   06cb53532f1b   Step2
       
  1658 |
       
  1659 o  <span style="color:olive;">1</span>   3eb38d10980d   Step1
       
  1660 ~
       
  1661 
       
  1662 </pre>
       
  1663 
       
  1664 #### Multi headed stack
       
  1665 
       
  1666 <pre>
       
  1667 $> hg stack
       
  1668 ###### topic: <span style="color:green;">myfeature</span> (<span style="color:olive;">2 heads</span>)
       
  1669 ###### branch: feature
       
  1670 <span style="color:teal;">t6</span><span style="color:teal;font-weight:bold;">@</span> <span style="color:teal;">Step4.5</span><span style="color:teal;font-weight:bold;"> (current)</span>
       
  1671 <span style="color:grey;">t4^ Step4 (base)</span>
       
  1672 <span style="color:olive;">t5</span><span style="color:green;">:</span> Step5
       
  1673 <span style="color:olive;">t4</span><span style="color:green;">:</span> Step4
       
  1674 <span style="color:olive;">t3</span><span style="color:green;">:</span> Step3
       
  1675 <span style="color:olive;">t2</span><span style="color:green;">:</span> Step2
       
  1676 <span style="color:olive;">t1</span><span style="color:green;">:</span> Step1
       
  1677 <span style="color:grey;">t0^ Trunk</span>
       
  1678 </pre>
       
  1679 
       
  1680 ## Distributed Workflow
       
  1681 
       
  1682 #### propagation
       
  1683 
       
  1684 Obsolescence can be exchanged:
       
  1685 
       
  1686 * push, pull
       
  1687 * bundle / unbundle (hg 4.3+)
       
  1688 
       
  1689 (affects draft history only)
       
  1690 
       
  1691 #### Exchanging draft
       
  1692 
       
  1693  * Works on multiple machines
       
  1694 
       
  1695  * Collaborate with others
       
  1696 
       
  1697  * Whole new play field == new traps
       
  1698 
       
  1699 #### Example
       
  1700 
       
  1701 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  1702 <div class='left' style='order:1; width: 50%'>
       
  1703 ~~~graphviz
       
  1704     digraph G {
       
  1705         rankdir="BT";
       
  1706         graph[splines=polyline];
       
  1707         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  1708 
       
  1709         // Revisions
       
  1710         node[group=main];
       
  1711         Root -> "A";
       
  1712         Root [shape="circle"];
       
  1713     }
       
  1714 ~~~
       
  1715 </div>
       
  1716 
       
  1717 <div class='right' style='order:2; width: 50%'>
       
  1718 ~~~graphviz
       
  1719     digraph G {
       
  1720         rankdir="BT";
       
  1721         graph[splines=polyline];
       
  1722         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  1723 
       
  1724         // Revisions
       
  1725         node[group=main];
       
  1726         Root -> "A";
       
  1727         Root [shape="circle"];
       
  1728     }
       
  1729 ~~~
       
  1730 </div>
       
  1731 </div>
       
  1732 
       
  1733 #### time pass
       
  1734 
       
  1735 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  1736 <div class='left' style='order:1; width: 50%'>
       
  1737 ~~~graphviz
       
  1738     digraph G {
       
  1739         rankdir="BT";
       
  1740         graph[splines=polyline];
       
  1741         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  1742 
       
  1743         // Revisions
       
  1744         node[group=main];
       
  1745         Root -> "A1";
       
  1746         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  1747         Root -> "A";
       
  1748 
       
  1749         // Obsolescence links
       
  1750         edge[dir=back, style=dotted, arrowtail=dot];
       
  1751         "A" -> "A1";
       
  1752 
       
  1753         Root [shape="circle"];
       
  1754     }
       
  1755 ~~~
       
  1756 </div>
       
  1757 
       
  1758 <div class='right' style='order:2; width: 50%'>
       
  1759 ~~~graphviz
       
  1760     digraph G {
       
  1761         rankdir="BT";
       
  1762         graph[splines=polyline];
       
  1763         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  1764 
       
  1765         // Revisions
       
  1766         node[group=main];
       
  1767         Root -> "A" -> B;
       
  1768 
       
  1769         Root [shape="circle"];
       
  1770     }
       
  1771 ~~~
       
  1772 </div>
       
  1773 </div>
       
  1774 
       
  1775 #### Instability
       
  1776 
       
  1777 ~~~graphviz
       
  1778     digraph G {
       
  1779         rankdir="BT";
       
  1780         graph[splines=polyline];
       
  1781         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  1782 
       
  1783         // Revisions
       
  1784         node[group=main];
       
  1785         Root -> "A1";
       
  1786         "B";
       
  1787         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  1788         Root -> "A" -> "B";
       
  1789 
       
  1790         // Obsolescence links
       
  1791         edge[dir=back, style=dotted, arrowtail=dot];
       
  1792         "A" -> "A1";
       
  1793 
       
  1794         Root [shape="circle"];
       
  1795         B [fillcolor="#FF3535"];
       
  1796     }
       
  1797 ~~~
       
  1798 
       
  1799 #### It's smart
       
  1800 
       
  1801 <img src="https://media2.giphy.com/media/ZThQqlxY5BXMc/giphy.gif">
       
  1802 
       
  1803 #### Stabilization
       
  1804 
       
  1805 ~~~graphviz
       
  1806     digraph G {
       
  1807         rankdir="BT";
       
  1808         graph[splines=polyline];
       
  1809         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  1810 
       
  1811         // Revisions
       
  1812         node[group=main];
       
  1813         Root -> "A1" -> "B1";
       
  1814         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  1815         Root -> "A" -> "B";
       
  1816 
       
  1817         // Obsolescence links
       
  1818         edge[dir=back, style=dotted, arrowtail=dot];
       
  1819         "A" -> "A1";
       
  1820         "B" -> "B1";
       
  1821 
       
  1822         Root [shape="circle"];
       
  1823     }
       
  1824 ~~~
       
  1825 
       
  1826 #### rewrite anything?
       
  1827 
       
  1828 Phases enforce a reliable history:
       
  1829 
       
  1830 * **draft**: can we rewritten
       
  1831 * **public**: immutable part of the history
       
  1832 
       
  1833 Contact your local workflow manager.
       
  1834 
       
  1835 ## Helpfull Tooling
       
  1836 
       
  1837 #### Summary
       
  1838 
       
  1839 <pre>
       
  1840 $> hg summary
       
  1841 <span style="color:olive;">parent: 10:890ac95deb83 </span>tip (unstable)
       
  1842  Head
       
  1843 branch: feature
       
  1844 commit: (clean)
       
  1845 update: (current)
       
  1846 phases: 9 draft
       
  1847 unstable: <span style="color:red;">1 changesets</span>
       
  1848 topic:  <span style="color:green;">myfeature</span>
       
  1849 </pre>
       
  1850 
       
  1851 #### Topics
       
  1852 
       
  1853 <pre>
       
  1854 $> hg topics
       
  1855    4.3compat
       
  1856    doc
       
  1857    evolvecolor
       
  1858    import-checker
       
  1859    more-output
       
  1860    obscache
       
  1861    obsfatefixes
       
  1862    obsmarkerbitfield
       
  1863    obsrangecacheiterative
       
  1864    packaging
       
  1865    prev-next
       
  1866    split
       
  1867    stack_unstable_bug
       
  1868    tutorial
       
  1869  * tutorialtypos
       
  1870 </pre>
       
  1871 
       
  1872 #### Topics age
       
  1873 
       
  1874 <pre>
       
  1875 $> hg topics --age
       
  1876    tutorial               (5 hours ago)
       
  1877 <span style="color:green;"> * </span><span style="color:green;">tutorialtypos         </span> (5 hours ago)
       
  1878    4.3compat              (4 days ago)
       
  1879    prev-next              (12 days ago)
       
  1880    obsfatefixes           (2 weeks ago)
       
  1881    more-output            (3 weeks ago)
       
  1882    obsmarkerbitfield      (2 months ago)
       
  1883    obscache               (2 months ago)
       
  1884    evolvecolor            (2 months ago)
       
  1885    obsrangecacheiterative (2 months ago)
       
  1886    stack_unstable_bug     (2 months ago)
       
  1887    doc                    (3 months ago)
       
  1888    split                  (3 months ago)
       
  1889    import-checker         (4 months ago)
       
  1890    packaging              (4 months ago)
       
  1891 </pre>
       
  1892 
       
  1893 #### Topics verbose
       
  1894 
       
  1895 <pre class="shell_output">
       
  1896 $> hg topics --verbose
       
  1897    4.3compat              (on branch: default, 1 changesets, <span style="color:teal;">43 behind</span>)
       
  1898    doc                    (on branch: stable, 1 changesets, <span style="color:teal;">415 behind</span>)
       
  1899    evolvecolor            (on branch: default, 1 changesets, <span style="color:teal;">369 behind</span>)
       
  1900    import-checker         (on branch: default, 1 changesets, <span style="color:teal;">637 behind</span>)
       
  1901    more-output            (on branch: default, 1 changesets, <span style="color:teal;">104 behind</span>)
       
  1902    obscache               (on branch: default, 1 changesets, <span style="color:teal;">325 behind</span>)
       
  1903    obsfatefixes           (on branch: default, 1 changesets, <span style="color:teal;">82 behind</span>)
       
  1904    obsmarkerbitfield      (on branch: default, 1 changesets, <span style="color:teal;">324 behind</span>)
       
  1905    obsrangecacheiterative (on branch: default, 1 changesets, <span style="color:teal;">461 behind</span>)
       
  1906    packaging              (on branch: default, 1 changesets, <span style="color:teal;">2521 behind</span>)
       
  1907    prev-next              (on branch: default, 4 changesets, <span style="color:teal;">72 behind</span>)
       
  1908    split                  (on branch: default, 1 changesets, <span style="color:teal;">492 behind</span>)
       
  1909    stack_unstable_bug     (on branch: default, 1 changesets, <span style="color:teal;">474 behind</span>)
       
  1910    tutorial               (on branch: default, 2 changesets, <span style="color:teal;">492 behind</span>)
       
  1911 <span style="color:green;"> * </span><span style="color:green;">tutorialtypos         </span> (on branch: default, 3 changesets, <span style="color:red;">1 troubled</span>, <span style="color:olive;">2 heads</span>, <span style="color:teal;">2 behind</span>)
       
  1912 </pre>
       
  1913 
       
  1914 #### Log
       
  1915 
       
  1916 <pre>
       
  1917 $ hg log -G --hidden -T '{node|short}\n{obsfate}\n'
       
  1918 @  c55cb2ee8a91
       
  1919 |
       
  1920 o  23abfc79b7ce
       
  1921 |
       
  1922 | o  4302274177b9 <span style="color:red;">(unstable)</span>
       
  1923 | |
       
  1924 | <span style="color:grey;">x  fba593aaaa10</span>
       
  1925 |/   rewritten as c55cb2ee8a91;
       
  1926 o  2ff53d8bf7d7
       
  1927 </pre>
       
  1928 
       
  1929 #### Evolve --list
       
  1930 
       
  1931 <pre>
       
  1932 $> hg evolve --list
       
  1933 <span style="color:gold;">9ac0d376e01c</span>: changelog: introduce a 'tiprev' method
       
  1934   <span style="color:red;">unstable</span>: <span style="color:grey;">52ec3072fe46</span> (obsolete parent)
       
  1935 
       
  1936 <span style="color:gold;">3efd3eab9860</span>: changelog: use 'tiprev()' in 'tip()'
       
  1937   <span style="color:red;">unstable</span>: <span style="color:red;">9ac0d376e01c</span> (unstable parent)
       
  1938 </pre>
       
  1939 
       
  1940 (see also `hg evolve --list --rev`)
       
  1941 
       
  1942 #### Obslog
       
  1943 
       
  1944 <pre>
       
  1945 $> hg obslog
       
  1946 @  <span style="color:olive;">c55cb2ee8a91</span> <span style="color:blue;">(4)</span> A2
       
  1947 |
       
  1948 | o  <span style="color:olive;">4302274177b9</span> <span style="color:blue;">(2)</span> A1
       
  1949 |/
       
  1950 x  <span style="color:olive;">fba593aaaa10</span> <span style="color:blue;">(1)</span> A
       
  1951      rewritten(description, parent) as <span style="color:olive;">c55cb2ee8a91</span>
       
  1952        by <span style="color:green;">Boris Feld &lt;boris.feld@octobus.net&gt;</span>
       
  1953        <span style="color:teal;">(Thu Jun 22 00:00:29 2017 +0200)</span>
       
  1954      rewritten(description) as <span style="color:olive;">4302274177b9</span>
       
  1955        by <span style="color:green;">Boris Feld &lt;boris.feld@octobus.net&gt;</span>
       
  1956        <span style="color:teal;">(Thu Jun 22 00:00:28 2017 +0200)</span>
       
  1957 
       
  1958 </pre>
       
  1959 
       
  1960 #### Obslog --patch
       
  1961 
       
  1962 <pre>
       
  1963 $> hg obslog -p
       
  1964 @  <span style="color:olive;">f6b1dded9e95</span> <span style="color:blue;">(2)</span> A1
       
  1965 |
       
  1966 x  <span style="color:olive;">364e589e2bac</span> <span style="color:blue;">(1)</span> A
       
  1967      rewritten(description, parent) as <span style="color:olive;">a6be771bedcf</span>
       
  1968        by <span style="color:green;">Boris Feld &lt;boris.feld@octobus.net&gt;</span>
       
  1969        <span style="color:teal;">(Thu Jun 22 00:00:29 2017 +0200)</span>
       
  1970        (No patch available yet, changesets rebased)
       
  1971      rewritten(description) as <span style="color:olive;">f6b1dded9e95</span>
       
  1972        by <span style="color:green;">Boris Feld &lt;boris.feld@octobus.net&gt;</span>
       
  1973        <span style="color:teal;">(Thu Jun 22 00:00:28 2017 +0200)</span>
       
  1974        --- a/364e589e2bac-changeset-description
       
  1975        +++ b/f6b1dded9e95-changeset-description
       
  1976        @@ -1,1 +1,1 @@
       
  1977        -A
       
  1978        +A1
       
  1979 </pre>
       
  1980 
       
  1981 #### Journal
       
  1982 
       
  1983 <pre>
       
  1984 $> hg journal
       
  1985 previous locations of '.':
       
  1986 2fb6d364d453  commit --amend -m Step1
       
  1987 701fb5d73e07  update --rev t1
       
  1988 ae11635effb7  commit -A -m Step2
       
  1989 701fb5d73e07  commit -A -m Step
       
  1990 </pre>
       
  1991 
       
  1992 ## Semantic
       
  1993 
       
  1994 #### Use the right commands!
       
  1995 
       
  1996 <img src="https://media.giphy.com/media/uRb2p09vY8lEs/giphy.gif">
       
  1997 
       
  1998 #### smart commands
       
  1999 
       
  2000 <table>
       
  2001 <tr>
       
  2002 <th>Operation</th>
       
  2003 <th>command</th>
       
  2004 </tr>
       
  2005 <tr>
       
  2006 <td>Modify</td>
       
  2007 <td>`hg amend`<br></td>
       
  2008 </tr>
       
  2009 <tr>
       
  2010 <td>Remove</td>
       
  2011 <td>`hg prune`<br></td>
       
  2012 </tr>
       
  2013 <tr>
       
  2014 <td>Move</td>
       
  2015 <td>`hg grab`<br></td>
       
  2016 </tr>
       
  2017 <tr>
       
  2018 <td>Split</td>
       
  2019 <td>`hg split`<br></td>
       
  2020 </tr>
       
  2021 <tr>
       
  2022 <td>Fold</td>
       
  2023 <td>`hg fold`<br></td>
       
  2024 </tr>
       
  2025 </table>
       
  2026 
       
  2027 
       
  2028 ## Troubles
       
  2029 
       
  2030 #### Evolution
       
  2031 
       
  2032 * Unlock powerful unique features
       
  2033 
       
  2034 * Hide **most** of the complexity
       
  2035 
       
  2036 * Help with unstable situations
       
  2037 
       
  2038     - Automatic detection
       
  2039 
       
  2040     - Automated resolution `hg help evolve`
       
  2041 
       
  2042 #### instability
       
  2043 
       
  2044 (currently: *troubles*)
       
  2045 
       
  2046 * **Orphans:** ancestors were rewritten
       
  2047 
       
  2048 * **Divergence:** branching in evolutions
       
  2049 
       
  2050     - Content-divergence: independent rewrites
       
  2051 
       
  2052     - Phase-divergence: older version got published
       
  2053 
       
  2054 ## Conclusion
       
  2055 
       
  2056 #### Work in progress
       
  2057 
       
  2058 * Concepts are solid
       
  2059 * Implementation in progress
       
  2060 * Common case works fine
       
  2061 * Some rough edges
       
  2062 * Feedback → priority
       
  2063 
       
  2064 #### Use Evolution Today
       
  2065 
       
  2066 install `hg-evolve`
       
  2067 
       
  2068 <pre>
       
  2069 [extensions]
       
  2070 evolve=
       
  2071 topic= ## provides hg stack
       
  2072 </pre>
       
  2073 
       
  2074 #### Helps
       
  2075 
       
  2076 * Mailing-list: `evolve-testers@mercurial-scm.org`
       
  2077 * IRC channel: `#mercurial`
       
  2078 
       
  2079 #### Documentation
       
  2080 
       
  2081 * Documentation: <br/><small><https://www.mercurial-scm.org/doc/evolution/index.html></small>
       
  2082 * Wiki: <br/><small><https://www.mercurial-scm.org/wiki/EvolveExtension></small>
       
  2083 
       
  2084 ## Conclusion
       
  2085 
       
  2086 #### Rewrite all the things!
       
  2087 
       
  2088 <img src="https://cdn.meme.am/cache/instances/folder258/500x/54913258.jpg">
       
  2089 
       
  2090 #### Safety first!
       
  2091 
       
  2092 <img src="https://media.giphy.com/media/46vrhWWOJ4wHC/giphy.gif">
       
  2093 
       
  2094 ## extra - Troubles
       
  2095 
       
  2096 #### Obsolete
       
  2097 
       
  2098 ~~~graphviz
       
  2099     digraph G {
       
  2100         rankdir="BT";
       
  2101         graph[splines=polyline];
       
  2102         node[fixedsize=true, style="filled", width=1, height=1, fillcolor="#7F7FFF", shape="pentagon"];
       
  2103 
       
  2104 
       
  2105         node[group=main];
       
  2106         Root -> New;
       
  2107         node[group=obsolete];
       
  2108         Root -> Obsolete;
       
  2109 
       
  2110         // Obsolescence links
       
  2111         edge[dir=back, style=dotted, arrowtail=dot];
       
  2112         Obsolete -> New;
       
  2113 
       
  2114         Obsolete [fillcolor="#DFDFFF"];
       
  2115         Root[shape="circle"];
       
  2116     }
       
  2117 ~~~
       
  2118 
       
  2119 #### Unstable
       
  2120 
       
  2121 Now called `orphan`
       
  2122 
       
  2123 ~~~graphviz
       
  2124     digraph G {
       
  2125         rankdir="BT";
       
  2126         graph[splines=polyline];
       
  2127         node[fixedsize=true, style="filled", width=1, height=1, fillcolor="#7F7FFF", shape="pentagon"];
       
  2128 
       
  2129         node[group=main];
       
  2130         Root -> New;
       
  2131         node[group=obsolete];
       
  2132         Root -> Obsolete -> Unstable;
       
  2133 
       
  2134         // Obsolescence links
       
  2135         edge[dir=back, style=dotted, arrowtail=dot];
       
  2136         Obsolete -> New;
       
  2137 
       
  2138         Obsolete [fillcolor="#DFDFFF"];
       
  2139         Unstable [fillcolor="#FF3535"];
       
  2140         Root[shape="circle"];
       
  2141     }
       
  2142 ~~~
       
  2143 
       
  2144 #### Bumped
       
  2145 
       
  2146 Now called `Phase-divergent`
       
  2147 
       
  2148 ~~~graphviz
       
  2149     digraph G {
       
  2150         rankdir="BT";
       
  2151         graph[splines=polyline];
       
  2152         node[fixedsize=true, style="filled", width=1, height=1, fillcolor="#7F7FFF", shape="pentagon"];
       
  2153 
       
  2154         node[group=main];
       
  2155         Root -> New;
       
  2156         node[group=obsolete];
       
  2157         Root -> Obsolete;
       
  2158         node[group=bumped];
       
  2159         Root -> Bumped;
       
  2160 
       
  2161         // Obsolescence links
       
  2162         edge[dir=back, style=dotted, arrowtail=dot];
       
  2163         Obsolete -> New;
       
  2164         Obsolete -> Bumped;
       
  2165 
       
  2166         New [shape="circle"];
       
  2167         Obsolete [fillcolor="#DFDFFF"];
       
  2168         Bumped [fillcolor="#FF3535"];
       
  2169         Root[shape="circle"];
       
  2170     }
       
  2171 ~~~
       
  2172 
       
  2173 #### Divergent
       
  2174 
       
  2175 Now called `Content-divergent`
       
  2176 
       
  2177 ~~~graphviz
       
  2178     digraph G {
       
  2179         rankdir="BT";
       
  2180         graph[splines=polyline];
       
  2181         node[fixedsize=true, style="filled", width=1, height=1, fillcolor="#7F7FFF", shape="pentagon"];
       
  2182 
       
  2183         Root -> Base;
       
  2184         Root -> Divergent1;
       
  2185         Root -> Divergent2;
       
  2186 
       
  2187         // Obsolescence links
       
  2188         edge[dir=back, style=dotted, arrowtail=dot];
       
  2189         Base -> Divergent1;
       
  2190         Base -> Divergent2;
       
  2191 
       
  2192         Base [shape="pentagon", fillcolor="#DFDFFF"];
       
  2193         Divergent1 [fillcolor="#FF3535"];
       
  2194         Divergent2 [fillcolor="#FF3535"];
       
  2195         Root[shape="circle"];
       
  2196     }
       
  2197 ~~~
       
  2198 
       
  2199 ## extra-commands
       
  2200 
       
  2201 #### Amend
       
  2202 
       
  2203 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  2204 <div class='left' style='order:1; width: 20%'>
       
  2205 ~~~graphviz
       
  2206     digraph G {
       
  2207         rankdir="BT";
       
  2208         graph[splines=polyline];
       
  2209         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2210 
       
  2211         // Revisions
       
  2212         node[group=main];
       
  2213         Root -> "A";
       
  2214         Root [shape="circle"];
       
  2215     }
       
  2216 ~~~
       
  2217 </div>
       
  2218 
       
  2219 <div class="middle" style='order:2; width: 60%'>
       
  2220 To amend A:
       
  2221 
       
  2222     hg amend -m 'A1'
       
  2223 </div>
       
  2224 
       
  2225 <div class='right' style='order:2; width: 20%'>
       
  2226 ~~~graphviz
       
  2227     digraph G {
       
  2228         rankdir="BT";
       
  2229         graph[splines=polyline];
       
  2230         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2231 
       
  2232         // Revisions
       
  2233         node[group=main];
       
  2234         Root -> "A1";
       
  2235         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  2236         Root -> "A";
       
  2237 
       
  2238         // Obsolescence links
       
  2239         edge[dir=back, style=dotted, arrowtail=dot];
       
  2240         "A" -> "A1";
       
  2241         Root [shape="circle"];
       
  2242     }
       
  2243 ~~~
       
  2244 </div>
       
  2245 </div>
       
  2246 
       
  2247 #### Prune
       
  2248 
       
  2249 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  2250 <div class='left' style='order:1; width: 20%'>
       
  2251 ~~~graphviz
       
  2252     digraph G {
       
  2253         rankdir="BT";
       
  2254         graph[splines=polyline];
       
  2255         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2256 
       
  2257         // Revisions
       
  2258         node[group=main];
       
  2259         Root -> "A";
       
  2260         Root [shape="circle"];
       
  2261     }
       
  2262 ~~~
       
  2263 </div>
       
  2264 
       
  2265 <div class="middle" style='order:2; width: 60%'>
       
  2266 
       
  2267 To prune A:
       
  2268 
       
  2269     hg prune -r "desc(A)"
       
  2270 </div>
       
  2271 
       
  2272 <div class='right' style='order:2; width: 20%'>
       
  2273 ~~~graphviz
       
  2274     digraph G {
       
  2275         rankdir="BT";
       
  2276         graph[splines=polyline];
       
  2277         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2278 
       
  2279         Root [shape="circle"];
       
  2280 
       
  2281         // Revisions
       
  2282         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  2283         Root -> "A";
       
  2284     }
       
  2285 ~~~
       
  2286 </div>
       
  2287 </div>
       
  2288 
       
  2289 #### Rebase
       
  2290 
       
  2291 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  2292 <div class='left' style='order:1; width: 20%'>
       
  2293 ~~~graphviz
       
  2294     digraph G {
       
  2295         rankdir="BT";
       
  2296         graph[splines=polyline];
       
  2297         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2298 
       
  2299         // Revisions
       
  2300         node[group=branch];
       
  2301         Root -> B;
       
  2302         node[group=main];
       
  2303         Root -> "A";
       
  2304 
       
  2305         Root [shape="circle"];
       
  2306     }
       
  2307 ~~~
       
  2308 </div>
       
  2309 
       
  2310 <div class="middle" style='order:2; width: 60%'>
       
  2311 
       
  2312 In order to rebase A on top of B;
       
  2313 
       
  2314     hg rebase -r "desc(A)" -d "desc(B)"
       
  2315 
       
  2316 </div>
       
  2317 
       
  2318 <div class='right' style='order:2; width: 20%'>
       
  2319 ~~~graphviz
       
  2320     digraph G {
       
  2321         rankdir="BT";
       
  2322         graph[splines=polyline];
       
  2323         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2324 
       
  2325         // Revisions
       
  2326         node[group=branch];
       
  2327         Root -> B -> "A'";
       
  2328 
       
  2329         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  2330         Root -> "A";
       
  2331 
       
  2332         // Obsolescence links
       
  2333         edge[dir=back, style=dotted, arrowtail=dot];
       
  2334         "A" -> "A'";
       
  2335 
       
  2336         Root [shape="circle"];
       
  2337     }
       
  2338 ~~~
       
  2339 </div>
       
  2340 </div>
       
  2341 
       
  2342 #### Fold
       
  2343 
       
  2344 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  2345 <div class='left' style='order:1; width: 15%'>
       
  2346 
       
  2347 ~~~graphviz
       
  2348     digraph G {
       
  2349         rankdir="BT";
       
  2350         graph[splines=polyline];
       
  2351         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2352 
       
  2353         // Revisions
       
  2354         node[group=branch];
       
  2355         Root -> A -> B;
       
  2356 
       
  2357         Root [shape="circle"];
       
  2358     }
       
  2359 ~~~
       
  2360 </div>
       
  2361 
       
  2362 <div class="middle" style='order:2; width: 70%'>
       
  2363 
       
  2364 To fold A and B:
       
  2365 
       
  2366     hg fold -r "desc(A)" -r "desc(B)" -m "C"
       
  2367 
       
  2368 </div>
       
  2369 
       
  2370 <div class='right' style='order:2; width: 15%'>
       
  2371 
       
  2372 ~~~graphviz
       
  2373     digraph G {
       
  2374         rankdir="BT";
       
  2375         graph[splines=polyline];
       
  2376         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2377 
       
  2378         // Revisions
       
  2379         node[group=branch];
       
  2380         Root -> C;
       
  2381 
       
  2382         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  2383         Root -> A -> B;
       
  2384 
       
  2385         // Obsolescence links
       
  2386         edge[dir=back, style=dotted, arrowtail=dot];
       
  2387         "A" -> "C";
       
  2388         "B" -> "C";
       
  2389 
       
  2390         Root [shape="circle"];
       
  2391     }
       
  2392 ~~~
       
  2393 
       
  2394 </div>
       
  2395 </div>
       
  2396 
       
  2397 #### Split
       
  2398 
       
  2399 <div class='graph' style='display: flex ;align-items: stretch ;flex-flow: row wrap ; align-items: center;'>
       
  2400 <div class='left' style='order:1; width: 20%'>
       
  2401 ~~~graphviz
       
  2402     digraph G {
       
  2403         rankdir="BT";
       
  2404         graph[splines=polyline];
       
  2405         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2406 
       
  2407         // Revisions
       
  2408         node[group=branch];
       
  2409         Root -> A;
       
  2410 
       
  2411         Root [shape="circle"];
       
  2412     }
       
  2413 ~~~
       
  2414 </div>
       
  2415 
       
  2416 <div class="middle" style='order:2; width: 60%'>
       
  2417 
       
  2418 Split in two:
       
  2419 
       
  2420     hg split -r "desc(A)"
       
  2421 </div>
       
  2422 
       
  2423 <div class='right' style='order:2; width: 20%'>
       
  2424 ~~~graphviz
       
  2425     digraph G {
       
  2426         rankdir="BT";
       
  2427         graph[splines=polyline];
       
  2428         node[fixedsize=true, width=1, height=1, style="filled", fillcolor="#7F7FFF", shape="pentagon"];
       
  2429 
       
  2430         // Revisions
       
  2431         node[group=branch];
       
  2432         Root -> B -> C;
       
  2433 
       
  2434         node[group=obsolete, style="dotted, filled", fillcolor="#DFDFFF"];
       
  2435         Root -> A;
       
  2436 
       
  2437         // Obsolescence links
       
  2438         edge[dir=back, style=dotted, arrowtail=dot];
       
  2439         "A" -> "C";
       
  2440         "A" -> "B";
       
  2441 
       
  2442         Root [shape="circle"];
       
  2443     }
       
  2444 ~~~
       
  2445 </div>
       
  2446 </div>
       
  2447  -->