1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
---
layout: default
title: Working with subtree merge
description: How to use subtree merge to merge one repo into another as a subpath.
categories: git_ninjutsu
---
<p class="intro">There are times when submodules are not adequate for the task at hand. For example, blending multiple repos together into one single repo while still maintaining the history of each repo. To do this, the subtree merge strategy is a better solution.</p>
Setting up and doing the first merge
------------------------------------
For this example, we'll make an empty "parent" repo and some other repos into it as subpaths.
First, set up an empty repo for our example:
<pre class="terminal">
[tekkub@tekBook: ~/tmp master*]
$ mkdir test
[tekkub@tekBook: ~/tmp master*]
$ cd test
[tekkub@tekBook: ~/tmp/test master*]
$ git init
Initialized empty Git repository in /Users/tekkub/tmp/test/.git/
[tekkub@tekBook: ~/tmp/test master#]
$ touch .gitignore
[tekkub@tekBook: ~/tmp/test master#]
$ git add .gitignore
[tekkub@tekBook: ~/tmp/test master#]
$ git commit -m "initial commit"
[master (root-commit) 3146c2a] initial commit
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 .gitignore
</pre>
Now we'll subtree-merge the repo [tekkub/cork](https://github.com/tekkub/cork) into the repo at `cork/`
<pre class="terminal">
[tekkub@tekBook: ~/tmp/test master]
$ git remote add -f cork git://github.com/tekkub/cork.git
Updating cork
warning: no common commits
remote: Counting objects: 1732, done.
remote: Compressing objects: 100% (750/750), done.
remote: Total 1732 (delta 1086), reused 1558 (delta 967)
Receiving objects: 100% (1732/1732), 528.19 KiB | 621 KiB/s, done.
Resolving deltas: 100% (1086/1086), done.
From git://github.com/tekkub/cork
* [new branch] lastbuffed -> cork/lastbuffed
* [new branch] lock_n_mount -> cork/lock_n_mount
* [new branch] master -> cork/master
* [new branch] nothing_to_see_here -> cork/nothing_to_see_here
[tekkub@tekBook: ~/tmp/test master]
$ git merge -s ours --no-commit cork/master
Automatic merge went well; stopped before committing as requested
[tekkub@tekBook: ~/tmp/test master|MERGING]
$ git read-tree --prefix=cork/ -u cork/master
[tekkub@tekBook: ~/tmp/test master+|MERGING]
$ git commit -m "Subtree merged in cork"
[master fe0ca25] Subtree merged in cork
</pre>
Next, we'll merge in [tekkub/panda](https://github.com/tekkub/panda) into the path `panda/`
<pre class="terminal">
[tekkub@tekBook: ~/tmp/test master]
$ git remote add -f panda git://github.com/tekkub/panda.git
Updating panda
warning: no common commits
remote: Counting objects: 974, done.
remote: Compressing objects: 100% (722/722), done.
remote: Total 974 (delta 616), reused 399 (delta 251)
Receiving objects: 100% (974/974), 189.56 KiB, done.
Resolving deltas: 100% (616/616), done.
From git://github.com/tekkub/panda
* [new branch] master -> panda/master
* [new branch] transmute -> panda/transmute
[tekkub@tekBook: ~/tmp/test master]
$ git merge -s ours --no-commit panda/master
Automatic merge went well; stopped before committing as requested
[tekkub@tekBook: ~/tmp/test master|MERGING]
$ git read-tree --prefix=panda/ -u panda/master
[tekkub@tekBook: ~/tmp/test master+|MERGING]
$ git commit -m "Subtree merged in panda"
[master 726a2cd] Subtree merged in panda
</pre>
Finally, we're going to merge the subpath `modules/` from tekkub/cork into `cork2/`
<pre class="terminal">
tekkub@iSenberg ~/tmp/test master
$ git merge -s ours --no-commit cork/master
Automatic merge went well; stopped before committing as requested
tekkub@iSenberg ~/tmp/test master|MERGING
$ git read-tree --prefix=cork2/ -u cork/master:modules
tekkub@iSenberg ~/tmp/test master+|MERGING
$ git commit -m "Subtree merged in cork/modules"
[master f240057] Subtree merged in cork/modules
</pre>
Pulling in changes
------------------
If the merged repo changes in the future, you can pull in its changes by simply using the `-s subtree` flag:
<pre class="terminal">
[tekkub@tekBook: ~/tmp/test master]
$ git pull -s subtree panda master
</pre>
Resources
---------
* [How to use the subtree merge strategy](http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html)
|