Pulling And Merging From Upstream

This continues the example from multiple graphs.

Pulling And Merging

Work continues upstream:

$ cd graph-upstream
$ echo a >def-1
$ hg commit --add --message "def-1" 
adding def-1
$ cd ..

We want to pull and merge this work so as to base our patches on latest upstream:

$ cd graph-forkjoin
$ hg pgraph --status
created graph description from current tips
o    p_join
|\
o |  p_fork2
| |
| o  p_fork1
|/
o  p_root
|
@  default

So we pull:

$ hg pull ../graph-upstream
pulling from ../graph-upstream
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads)

and the situation in the repository is as follows:

$ hg glog
o  8    : def-1 - john
|
| o    7    p_join: merge of .p_join - john
| |\
| | o    6    .p_join: merge of p_fork2 - john
| | |\
| | | o  5    .p_join: update patch dependencies - john
| | | |
| | o |  4    p_fork2: start new patch on p_root - john
| | | |
| o---+  3    p_join: start new patch on p_fork1 - john
|  / /
| | o  2    p_fork1: start new patch on p_root - john
| |/
| o  1    p_root: start new patch on default - john
|/
@  0    : def-0 - john

To ripple the change in dev-1 through to all our patch branches, we need a lot of merges:

$ hg pgraph --status
o    p_join
|\    * needs merge with default (through .p_join, p_fork2, p_root)
| |   * needs merge with default (through .p_join, p_fork1, p_root)
o |  p_fork2
| |   * needs merge with default (through p_root)
| o  p_fork1
|/    * needs merge with default (through p_root)
o  p_root
|   * needs merge with default
|   * needs update of diff base to tip of default
@  default

We can do this in a single sweep by merging all pending heads:

$ hg pmerge --all
updating to default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
p_root: merging from default
marked working directory as branch p_root
(branches are permanent and global, did you want a bookmark?)
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
p_fork1: merging from p_root
marked working directory as branch p_fork1
(branches are permanent and global, did you want a bookmark?)
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
updating to p_root
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
p_fork2: merging from p_root
marked working directory as branch p_fork2
(branches are permanent and global, did you want a bookmark?)
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
created new head
.p_join: merging from p_fork2
marked working directory as branch .p_join
(branches are permanent and global, did you want a bookmark?)
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
updating to p_fork1
1 files updated, 0 files merged, 3 files removed, 0 files unresolved
.p_join: merging from p_fork1
marked working directory as branch .p_join
(branches are permanent and global, did you want a bookmark?)
merging .hgpatchinfo/p_fork1.dep
3 files updated, 1 files merged, 0 files removed, 0 files unresolved
p_join: merging from .p_join
marked working directory as branch p_join
(branches are permanent and global, did you want a bookmark?)
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

Reviewing Merges

This merge orgy resulted in a fairly complicated graph:

$ hg glog
@    14    p_join: merge of .p_join - john
|\
| o    13    .p_join: merge of p_fork1 - john
| |\
| | o    12    .p_join: merge of p_fork2 - john
| | |\
| | | o    11    p_fork2: merge of p_root - john
| | | |\
| o-----+  10    p_fork1: merge of p_root - john
| | | | |
| | | | o    9    p_root: merge of default - john
| | | | |\
| | | | | o  8    : def-1 - john
| | | | | |
o---+ | | |  7    p_join: merge of .p_join - john
| | | | | |
| | o | | |  6    .p_join: merge of p_fork2 - john
| | |\| | |
| | o | | |  5    .p_join: update patch dependencies - john
| |/ / / /
| | o / /  4    p_fork2: start new patch on p_root - john
| | |/ /
o | / /  3    p_join: start new patch on p_fork1 - john
|/ / /
o / /  2    p_fork1: start new patch on p_root - john
|/ /
o /  1    p_root: start new patch on default - john
|/
o  0    : def-0 - john

To review a merge, we can diff it and check that it didn’t do anything except what the patch is supposed to do. So we look at the patch:

$ hg pdiff p_root
# HG changeset patch
# User john
# Date 0 0
_
diff --git a/p_root b/p_root
new file mode 100644
--- /dev/null
+++ b/p_root
@@ -0,0 +1,1 @@
+a

and compare with the merge diff:

$ hg diff --change 9 -X .hgpatchinfo
diff --git a/p_root b/p_root
new file mode 100644
--- /dev/null
+++ b/p_root
@@ -0,0 +1,1 @@
+a

This works because pbranch always uses the base branch as the first parent of the merge.