diff tests/test-copytrace-heuristics.t @ 34179:036d47d7cf39

copytrace: move fast heuristic copytracing algorithm to core copytrace extension in fb-hgext has a heuristic implementation of copy tracing which is faster than the current copy tracing. The heuristic limits the search of copies to just files that are either: 1) Renames in the same directory 2) Moved to other directory with same name The default copytrace implementation is very slow as it finds all the new files that were added from merge base up to the head commit and for each file it checks whether it this was copied or moved version of a different file. Stash@fb did analysis for the above heuristics on the fb repo and found that among 2,443,768 moves/copies there are only 32,234 moves/copies which does not fall under the above heuristics which is approx. 0.013 of total copies. This patch moves the heuristics algorithm under config `experimental.copytrace=heuristics`. While moving fbext to core, this patch removes couple of less useful config options named `sourcecommitlimit` and `maxmovescandidatestocheck`. Tests are also added for the heuristics algorithm, which are basically copied from fbext/tests/test-copytrace.t. The tests follow a pattern creating a server repo and then cloning to a local repo to create public and draft changesets, the distinction which will be useful in upcoming patches. After this patch `experimental.copytrace` has the following behaviour: 1) `off`: turns off copytracing 2) `heuristics`: use the heuristic algorithm added in this patch. 3) everything else: use the full copytracing algorithm .. feature:: A new fast heuristic algorithm for copytracing which assumes that the files moves are either:: 1) Renames in the same directory 2) Moves in other directories with same names You can use this algorithm by setting `experimental.copytrace=heuristics`. Differential Revision: https://phab.mercurial-scm.org/D623
author Pulkit Goyal <7895pulkit@gmail.com>
date Sun, 03 Sep 2017 03:49:15 +0530
parents
children fc3b8483c6cb
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-copytrace-heuristics.t	Sun Sep 03 03:49:15 2017 +0530
@@ -0,0 +1,591 @@
+Test for the heuristic copytracing algorithm
+============================================
+
+  $ cat >> $TESTTMP/copytrace.sh << '__EOF__'
+  > initclient() {
+  > cat >> $1/.hg/hgrc <<EOF
+  > [experimental]
+  > copytrace = heuristics
+  > EOF
+  > }
+  > __EOF__
+  $ . "$TESTTMP/copytrace.sh"
+
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > rebase=
+  > shelve=
+  > EOF
+
+Check filename heuristics (same dirname and same basename)
+  $ hg init server
+  $ cd server
+  $ echo a > a
+  $ mkdir dir
+  $ echo a > dir/file.txt
+  $ hg addremove
+  adding a
+  adding dir/file.txt
+  $ hg ci -m initial
+  $ hg mv a b
+  $ hg mv -q dir dir2
+  $ hg ci -m 'mv a b, mv dir/ dir2/'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 0
+  $ echo b > a
+  $ echo b > dir/file.txt
+  $ hg ci -qm 'mod a, mod dir/file.txt'
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: 557f403c0afd2a3cf15d7e2fb1f1001a8b85e081
+  |   desc: mod a, mod dir/file.txt, phase: draft
+  | o  changeset: 928d74bc9110681920854d845c06959f6dfc9547
+  |/    desc: mv a b, mv dir/ dir2/, phase: public
+  o  changeset: 3c482b16e54596fed340d05ffaf155f156cda7ee
+      desc: initial, phase: public
+
+  $ hg rebase -s . -d 1
+  rebasing 2:557f403c0afd "mod a, mod dir/file.txt" (tip)
+  merging b and a to b
+  merging dir2/file.txt and dir/file.txt to dir2/file.txt
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/557f403c0afd-9926eeff-rebase.hg (glob)
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Make sure filename heuristics do not when they are not related
+  $ hg init server
+  $ cd server
+  $ echo 'somecontent' > a
+  $ hg add a
+  $ hg ci -m initial
+  $ hg rm a
+  $ echo 'completelydifferentcontext' > b
+  $ hg add b
+  $ hg ci -m 'rm a, add b'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 0
+  $ printf 'somecontent\nmoarcontent' > a
+  $ hg ci -qm 'mode a'
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: d526312210b9e8f795d576a77dc643796384d86e
+  |   desc: mode a, phase: draft
+  | o  changeset: 46985f76c7e5e5123433527f5c8526806145650b
+  |/    desc: rm a, add b, phase: public
+  o  changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0
+      desc: initial, phase: public
+
+  $ hg rebase -s . -d 1
+  rebasing 2:d526312210b9 "mode a" (tip)
+  other [source] changed a which local [dest] deleted
+  use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
+  unresolved conflicts (see hg resolve, then hg rebase --continue)
+  [1]
+
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Test when lca didn't modified the file that was moved
+  $ hg init server
+  $ cd server
+  $ echo 'somecontent' > a
+  $ hg add a
+  $ hg ci -m initial
+  $ echo c > c
+  $ hg add c
+  $ hg ci -m randomcommit
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 1
+  $ echo b > a
+  $ hg ci -qm 'mod a'
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: 9d5cf99c3d9f8e8b05ba55421f7f56530cfcf3bc
+  |   desc: mod a, phase: draft
+  | o  changeset: d760186dd240fc47b91eb9f0b58b0002aaeef95d
+  |/    desc: mv a b, phase: public
+  o  changeset: 48e1b6ba639d5d7fb313fa7989eebabf99c9eb83
+  |   desc: randomcommit, phase: public
+  o  changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0
+      desc: initial, phase: public
+
+  $ hg rebase -s . -d 2
+  rebasing 3:9d5cf99c3d9f "mod a" (tip)
+  merging b and a to b
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9d5cf99c3d9f-f02358cc-rebase.hg (glob)
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Rebase "backwards"
+  $ hg init server
+  $ cd server
+  $ echo 'somecontent' > a
+  $ hg add a
+  $ hg ci -m initial
+  $ echo c > c
+  $ hg add c
+  $ hg ci -m randomcommit
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 2
+  $ echo b > b
+  $ hg ci -qm 'mod b'
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: fbe97126b3969056795c462a67d93faf13e4d298
+  |   desc: mod b, phase: draft
+  o  changeset: d760186dd240fc47b91eb9f0b58b0002aaeef95d
+  |   desc: mv a b, phase: public
+  o  changeset: 48e1b6ba639d5d7fb313fa7989eebabf99c9eb83
+  |   desc: randomcommit, phase: public
+  o  changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0
+      desc: initial, phase: public
+
+  $ hg rebase -s . -d 0
+  rebasing 3:fbe97126b396 "mod b" (tip)
+  merging a and b to a
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fbe97126b396-cf5452a1-rebase.hg (glob)
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Rebase draft commit on top of draft commit
+  $ hg init repo
+  $ initclient repo
+  $ cd repo
+  $ echo 'somecontent' > a
+  $ hg add a
+  $ hg ci -m initial
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+  $ hg up -q ".^"
+  $ echo b > a
+  $ hg ci -qm 'mod a'
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: 5268f05aa1684cfb5741e9eb05eddcc1c5ee7508
+  |   desc: mod a, phase: draft
+  | o  changeset: 542cb58df733ee48fa74729bd2cdb94c9310d362
+  |/    desc: mv a b, phase: draft
+  o  changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0
+      desc: initial, phase: draft
+
+  $ hg rebase -s . -d 1
+  rebasing 2:5268f05aa168 "mod a" (tip)
+  merging b and a to b
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/5268f05aa168-284f6515-rebase.hg (glob)
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Check a few potential move candidates
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ mkdir dir
+  $ echo a > dir/a
+  $ hg add dir/a
+  $ hg ci -qm initial
+  $ hg mv dir/a dir/b
+  $ hg ci -qm 'mv dir/a dir/b'
+  $ mkdir dir2
+  $ echo b > dir2/a
+  $ hg add dir2/a
+  $ hg ci -qm 'create dir2/a'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 0
+  $ echo b > dir/a
+  $ hg ci -qm 'mod dir/a'
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: 6b2f4cece40fd320f41229f23821256ffc08efea
+  |   desc: mod dir/a, phase: draft
+  | o  changeset: 4494bf7efd2e0dfdd388e767fb913a8a3731e3fa
+  | |   desc: create dir2/a, phase: public
+  | o  changeset: b1784dfab6ea6bfafeb11c0ac50a2981b0fe6ade
+  |/    desc: mv dir/a dir/b, phase: public
+  o  changeset: 36859b8907c513a3a87ae34ba5b1e7eea8c20944
+      desc: initial, phase: public
+
+  $ hg rebase -s . -d 2
+  rebasing 3:6b2f4cece40f "mod dir/a" (tip)
+  merging dir/b and dir/a to dir/b
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/6b2f4cece40f-503efe60-rebase.hg (glob)
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Move file in one branch and delete it in another
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ echo a > a
+  $ hg add a
+  $ hg ci -m initial
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+  $ hg up -q ".^"
+  $ hg rm a
+  $ hg ci -m 'del a'
+  created new head
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: 7d61ee3b1e48577891a072024968428ba465c47b
+  |   desc: del a, phase: draft
+  | o  changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
+  |/    desc: mv a b, phase: draft
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+
+  $ hg rebase -s 1 -d 2
+  rebasing 1:472e38d57782 "mv a b"
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/472e38d57782-17d50e29-rebase.hg (glob)
+  $ hg up -q c492ed3c7e35dcd1dc938053b8adf56e2cfbd062
+  $ ls
+  b
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Move a directory in draft branch
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ mkdir dir
+  $ echo a > dir/a
+  $ hg add dir/a
+  $ hg ci -qm initial
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ echo b > dir/a
+  $ hg ci -qm 'mod dir/a'
+  $ hg up -q ".^"
+  $ hg mv -q dir/ dir2
+  $ hg ci -qm 'mv dir/ dir2/'
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: a33d80b6e352591dfd82784e1ad6cdd86b25a239
+  |   desc: mv dir/ dir2/, phase: draft
+  | o  changeset: 6b2f4cece40fd320f41229f23821256ffc08efea
+  |/    desc: mod dir/a, phase: draft
+  o  changeset: 36859b8907c513a3a87ae34ba5b1e7eea8c20944
+      desc: initial, phase: public
+
+  $ hg rebase -s . -d 1
+  rebasing 2:a33d80b6e352 "mv dir/ dir2/" (tip)
+  merging dir/a and dir2/a to dir2/a
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/a33d80b6e352-fecb9ada-rebase.hg (glob)
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Move file twice and rebase mod on top of moves
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ echo a > a
+  $ hg add a
+  $ hg ci -m initial
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+  $ hg mv b c
+  $ hg ci -m 'mv b c'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 0
+  $ echo c > a
+  $ hg ci -m 'mod a'
+  created new head
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: d413169422167a3fa5275fc5d71f7dea9f5775f3
+  |   desc: mod a, phase: draft
+  | o  changeset: d3efd280421d24f9f229997c19e654761c942a71
+  | |   desc: mv b c, phase: public
+  | o  changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
+  |/    desc: mv a b, phase: public
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+  $ hg rebase -s . -d 2
+  rebasing 3:d41316942216 "mod a" (tip)
+  merging c and a to c
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d41316942216-2b5949bc-rebase.hg (glob)
+
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Move file twice and rebase moves on top of mods
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ echo a > a
+  $ hg add a
+  $ hg ci -m initial
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+  $ hg mv b c
+  $ hg ci -m 'mv b c'
+  $ hg up -q 0
+  $ echo c > a
+  $ hg ci -m 'mod a'
+  created new head
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: d413169422167a3fa5275fc5d71f7dea9f5775f3
+  |   desc: mod a, phase: draft
+  | o  changeset: d3efd280421d24f9f229997c19e654761c942a71
+  | |   desc: mv b c, phase: draft
+  | o  changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
+  |/    desc: mv a b, phase: draft
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+  $ hg rebase -s 1 -d .
+  rebasing 1:472e38d57782 "mv a b"
+  merging a and b to b
+  rebasing 2:d3efd280421d "mv b c"
+  merging b and c to c
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/472e38d57782-ab8d3c58-rebase.hg (glob)
+
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Move one file and add another file in the same folder in one branch, modify file in another branch
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ echo a > a
+  $ hg add a
+  $ hg ci -m initial
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+  $ echo c > c
+  $ hg add c
+  $ hg ci -m 'add c'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 0
+  $ echo b > a
+  $ hg ci -m 'mod a'
+  created new head
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e
+  |   desc: mod a, phase: draft
+  | o  changeset: b1a6187e79fbce851bb584eadcb0cc4a80290fd9
+  | |   desc: add c, phase: public
+  | o  changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
+  |/    desc: mv a b, phase: public
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+
+  $ hg rebase -s . -d 2
+  rebasing 3:ef716627c70b "mod a" (tip)
+  merging b and a to b
+  saved backup bundle to $TESTTMP/repo/.hg/strip-backup/ef716627c70b-24681561-rebase.hg (glob)
+  $ ls
+  b
+  c
+  $ cat b
+  b
+
+Merge test
+  $ hg init server
+  $ cd server
+  $ echo a > a
+  $ hg add a
+  $ hg ci -m initial
+  $ echo b > a
+  $ hg ci -m 'modify a'
+  $ hg up -q 0
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+  created new head
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 2
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
+  |   desc: mv a b, phase: public
+  | o  changeset: b0357b07f79129a3d08a68621271ca1352ae8a09
+  |/    desc: modify a, phase: public
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+
+  $ hg merge 1
+  merging b and a to b
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m merge
+  $ ls
+  b
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Copy and move file
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ echo a > a
+  $ hg add a
+  $ hg ci -m initial
+  $ hg cp a c
+  $ hg mv a b
+  $ hg ci -m 'cp a c, mv a b'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q 0
+  $ echo b > a
+  $ hg ci -m 'mod a'
+  created new head
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e
+  |   desc: mod a, phase: draft
+  | o  changeset: 4fc3fd13fbdb89ada6b75bfcef3911a689a0dde8
+  |/    desc: cp a c, mv a b, phase: public
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+
+  $ hg rebase -s . -d 1
+  rebasing 2:ef716627c70b "mod a" (tip)
+  merging b and a to b
+  merging c and a to c
+  saved backup bundle to $TESTTMP/repo/repo/.hg/strip-backup/ef716627c70b-24681561-rebase.hg (glob)
+  $ ls
+  b
+  c
+  $ cat b
+  b
+  $ cat c
+  b
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Do a merge commit with many consequent moves in one branch
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ echo a > a
+  $ hg add a
+  $ hg ci -m initial
+  $ echo b > a
+  $ hg ci -qm 'mod a'
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ hg up -q ".^"
+  $ hg mv a b
+  $ hg ci -qm 'mv a b'
+  $ hg mv b c
+  $ hg ci -qm 'mv b c'
+  $ hg up -q 1
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  o  changeset: d3efd280421d24f9f229997c19e654761c942a71
+  |   desc: mv b c, phase: draft
+  o  changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
+  |   desc: mv a b, phase: draft
+  | @  changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e
+  |/    desc: mod a, phase: public
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+
+  $ hg merge 3
+  merging a and c to c
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -qm 'merge'
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @    changeset: cd29b0d08c0f39bfed4cde1b40e30f419db0c825
+  |\    desc: merge, phase: draft
+  | o  changeset: d3efd280421d24f9f229997c19e654761c942a71
+  | |   desc: mv b c, phase: draft
+  | o  changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
+  | |   desc: mv a b, phase: draft
+  o |  changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e
+  |/    desc: mod a, phase: public
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+  $ ls
+  c
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo
+
+Test shelve/unshelve
+  $ hg init server
+  $ initclient server
+  $ cd server
+  $ echo a > a
+  $ hg add a
+  $ hg ci -m initial
+  $ cd ..
+  $ hg clone -q server repo
+  $ initclient repo
+  $ cd repo
+  $ echo b > a
+  $ hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg mv a b
+  $ hg ci -m 'mv a b'
+
+  $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
+  @  changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
+  |   desc: mv a b, phase: draft
+  o  changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
+      desc: initial, phase: public
+  $ hg unshelve
+  unshelving change 'default'
+  rebasing shelved changes
+  rebasing 2:45f63161acea "changes to: initial" (tip)
+  merging b and a to b
+  $ ls
+  b
+  $ cat b
+  b
+  $ cd ..
+  $ rm -rf server
+  $ rm -rf repo