Test of the hg evolve extension for easier upstreaming

* Rationale

Currently I rework my code extensively before I push it into upstream SVN. Some of that is inconvenient and it would be nicer to have easy to use refactoring tools.

[[http://hg-lab.logilab.org/doc/mutable-history/html/index.html][hg evolve]] might offer that.

* Tests
  :PROPERTIES:
  :tangle:   runtests.sh
  :noweb: yes
  :END:

#+BEGIN_SRC sh :shebang #!/bin/sh :exports both :results output verbatim
# Tests for refactoring history with the evolve extension
#+END_SRC

** Init

/Initialize the repos I need for the test/

We have one public repo and 2 nonpublishing repos.

#+BEGIN_SRC sh :exports both :results output verbatim
# Initialize the test repo
hg init testpublic # a public repo
hg init testmy # my repo
hg init testother # other repo
# make the two private repos nonpublishing
for i in my other
  do echo "[ui]
username = $i
[phases]
publish = False" > test${i}/.hg/hgrc
done
#+END_SRC

#+RESULTS:

** Prepare

/Prepare the content of the repos/

#+BEGIN_SRC sh  :exports both :results output verbatim
cd testmy
echo "Hello World" > hello.txt
hg ci -Am "Hello World"
hg log -G
cd ..
#+END_SRC   

#+RESULTS:
| Füge             | hello.txt | hinzu          |   |          |      |       |
| @                | Änderung: | 0:6f9dbac57286 |   |          |      |       |
| Marke:           | tip       |                |   |          |      |       |
| Nutzer:          | my        |                |   |          |      |       |
| Datum:           | Wed       | Jan            | 9 | 19:51:12 | 2013 | +0100 |
| Zusammenfassung: | Hello     | World          |   |          |      |       |
|                  |           |                |   |          |      |       |

** Amend

/Add a bad change and amend it./

#+BEGIN_SRC sh :exports both :results output verbatim
cd testmy
sed -i s/World/Evoluton/ hello.txt
hg ci -m "Hello Evolution"
hg log -G
cat hello.txt
echo FIX this up
sed -i s/Evoluton/Evolution/ hello.txt
hg amend -m "Hello Evolution" # pass the message explicitely again to avoid having the editor pop up
hg log -G
cd ..
#+END_SRC

#+RESULTS:
| @                | Änderung: | 1:b59dc2fddce4   |                |           |      |          |      |       |
|                  |           | Marke:           | tip            |           |      |          |      |       |
|                  |           | Nutzer:          | my             |           |      |          |      |       |
|                  |           | Datum:           | Wed            | Jan       |    9 | 19:51:18 | 2013 | +0100 |
|                  |           | Zusammenfassung: | Hello          | Evolution |      |          |      |       |
|                  |           |                  |                |           |      |          |      |       |
| o                | Änderung: | 0:6f9dbac57286   |                |           |      |          |      |       |
| Nutzer:          | my        |                  |                |           |      |          |      |       |
| Datum:           | Wed       | Jan              | 9              | 19:51:12  | 2013 |    +0100 |      |       |
| Zusammenfassung: | Hello     | World            |                |           |      |          |      |       |
|                  |           |                  |                |           |      |          |      |       |
| Hello            | Evoluton  |                  |                |           |      |          |      |       |
| FIX              | this      | up               |                |           |      |          |      |       |
| @                | Änderung: | 3:84523157dd67   |                |           |      |          |      |       |
|                  |           | Marke:           | tip            |           |      |          |      |       |
|                  |           | Vorgänger:       | 0:6f9dbac57286 |           |      |          |      |       |
|                  |           | Nutzer:          | my             |           |      |          |      |       |
|                  |           | Datum:           | Wed            | Jan       |    9 | 19:51:18 | 2013 | +0100 |
|                  |           | Zusammenfassung: | Hello          | Evolution |      |          |      |       |
|                  |           |                  |                |           |      |          |      |       |
| o                | Änderung: | 0:6f9dbac57286   |                |           |      |          |      |       |
| Nutzer:          | my        |                  |                |           |      |          |      |       |
| Datum:           | Wed       | Jan              | 9              | 19:51:12  | 2013 |    +0100 |      |       |
| Zusammenfassung: | Hello     | World            |                |           |      |          |      |       |
|                  |           |                  |                |           |      |          |      |       |

** …together

/Add a bad change. Followed by a good change. Pull both into another repo and amend it. Do a good change in the other repo. Then amend the bad change in the original repo, pull it into the other and evolve./

*** Setup

Now we change the format to planning a roleplaying session to have a more complex task. We want to present this as coherent story on how to plan a story, so we want clean history.

First I do my own change.

#+BEGIN_SRC sh :exports both :results output verbatim
cd testmy
# Now we add the bad change
echo "Wishes:

- The Solek wants Action
- The Judicator wants Action

" >> plan.txt
hg ci -Am "What the players want"
# show what we did
hg log -G -r tip
# and the good change
echo "Places: 

- The village
- The researchers cave

" >> plan.txt
hg ci -m "The places"
hg log -G
cd ..
#+END_SRC

No my file contains the wishes of the players as well as the places.

Now we pull the changes into the repo of another game master with whom we plan this game. He adds the important people:

#+BEGIN_SRC sh :exports both :results output verbatim
hg -R testother pull -u testmy
cd testother
echo "People:

- The Lost
- The Specter

" >> plan.txt
hg ci -m "The people"
hg log -G
cd ..
#+END_SRC

*** Fix my side

And I realize too late, that my estimate of the wishes of the players was wrong. So I simply amend it.

#+BEGIN_SRC sh :exports both :results output verbatim
cd testmy
hg up -r -2
sed -i "s/The Solek wants Action/The Solek wants emotionally intense situations/" plan.txt
hg amend -m "The wishes of the players"
hg log -G
cd ..
#+END_SRC

Now I amended my commit, but my history does not look good, yet. Actually it looks evil, since I have 2 heads, which is not so nice. The changeset under which we just pulled away the bad change has become unstable, because its ancestor has been obsoleted, so it has no stable foothold anymore. In other DVCSs, this means that we as users have to find out what was changed and fix it ourselves.

Changeset evolution allows us to evolve our repository to get rid of dependencies on obsolete changes.

#+BEGIN_SRC sh :exports both :results output verbatim
cd testmy
hg evolve
hg log -G
cd ..
#+END_SRC

Now I have nice looking history without any hassle - and without having to resort to low-level commands.

*** Be a nice neighbor

But I rewrote history. What happens if my collegue pulls this? 

#+BEGIN_SRC sh :exports both :results output verbatim
hg -R testother pull testmy
hg -R testother log -G
#+END_SRC

As you can see, he is told that his changes became unstable, since they depend on obsolete history. No need to panic: He can just evolve his repo to be state of the art again.

#+BEGIN_SRC sh :exports both :results output verbatim
hg -R testother evolve
#+END_SRC

But the unstable change is the current working directory, so evolve does not change it. Instead it tells us, that we might want to call it with `--any`. And as it is the case with most hints in hg, that is actually the case.

/note: that message might be a candidate for cleanup./

#+BEGIN_SRC sh :exports both :results output verbatim
hg -R testother evolve --any
hg -R testother log -G
#+END_SRC

And as you can see, everything looks nice again.

** Fold

/Do multiple commits to create a patch, then fold them into one commit./

Now I go into a bit of a planning spree. 

#+BEGIN_SRC sh :tangle no :exports both :results output verbatim
cd testmy
echo "Scenes:
" >> plan.txt
hg ci -m "we need scenes"

echo "- Lost appears" >> plan.txt
hg ci -m "scene"
echo "- People vanish" >> plan.txt
hg ci -m "scene"
echo "- Portals during dreamtime" >> plan.txt
hg ci -m "scene"
hg log -G
cd ..
#+END_SRC 

Yes, I tend to do that… 

But we actually only need one change, so make it one by folding the last 4 changes changes into a single commit. Since fold does not take -m, yet, we will stop here for now.

#+BEGIN_SRC sh :tangle no :exports both :results output verbatim
cd testmy
# hg fold -r "-1:-4"
# hg log -G
cd ..
#+END_SRC

** Split

/Do one big commit, then split it into two atomic commits./

Now I apply the scenes to wishes, places and people. Which is not useful: First I should apply them to the wishes and check if all wishes are fullfilled. But while writing I forgot that, and anxious to show my co-gamemaster, I just did one big commit.

#+BEGIN_SRC sh :exports both :results output verbatim
cd testmy
sed -i "s/The Judicator wants Action/The Judicator wants Action - Portals/" plan.txt
sed -i "s/The village/The village - lost appears, people wanish, portals during dreamtime/" plan.txt
hg ci -m "Apply Scenes to people and places."
hg log -G
cd ..
#+END_SRC

Let’s fix that.



** …as afterthought

/Do one big commit, add an atomic commit. Then split the big commit./

** …together