| 1 | Date: Sat, 5 Jan 2008 20:17:40 -0500 |
| 2 | From: Sean <seanlkml@sympatico.ca> |
| 3 | To: Miklos Vajna <vmiklos@frugalware.org> |
| 4 | Cc: git@vger.kernel.org |
| 5 | Subject: how to use git merge -s subtree? |
| 6 | Abstract: In this article, Sean demonstrates how one can use the subtree merge |
| 7 | strategy. |
| 8 | Content-type: text/asciidoc |
| 9 | Message-ID: <BAYC1-PASMTP12374B54BA370A1E1C6E78AE4E0@CEZ.ICE> |
| 10 | |
| 11 | How to use the subtree merge strategy |
| 12 | ===================================== |
| 13 | |
| 14 | There are situations where you want to include content in your project |
| 15 | from an independently developed project. You can just pull from the |
| 16 | other project as long as there are no conflicting paths. |
| 17 | |
| 18 | The problematic case is when there are conflicting files. Potential |
| 19 | candidates are Makefiles and other standard filenames. You could merge |
| 20 | these files but probably you do not want to. A better solution for this |
| 21 | problem can be to merge the project as its own subdirectory. This is not |
| 22 | supported by the 'recursive' merge strategy, so just pulling won't work. |
| 23 | |
| 24 | What you want is the 'subtree' merge strategy, which helps you in such a |
| 25 | situation. |
| 26 | |
| 27 | In this example, let's say you have the repository at `/path/to/B` (but |
| 28 | it can be a URL as well, if you want). You want to merge the 'master' |
| 29 | branch of that repository to the `dir-B` subdirectory in your current |
| 30 | branch. |
| 31 | |
| 32 | Here is the command sequence you need: |
| 33 | |
| 34 | ---------------- |
| 35 | $ git remote add -f Bproject /path/to/B <1> |
| 36 | $ git merge -s ours --no-commit --allow-unrelated-histories Bproject/master <2> |
| 37 | $ git read-tree --prefix=dir-B/ -u Bproject/master <3> |
| 38 | $ git commit -m "Merge B project as our subdirectory" <4> |
| 39 | |
| 40 | $ git pull -s subtree Bproject master <5> |
| 41 | ---------------- |
| 42 | <1> name the other project "Bproject", and fetch. |
| 43 | <2> prepare for the later step to record the result as a merge. |
| 44 | <3> read "master" branch of Bproject to the subdirectory "dir-B". |
| 45 | <4> record the merge result. |
| 46 | <5> maintain the result with subsequent merges using "subtree" |
| 47 | |
| 48 | The first four commands are used for the initial merge, while the last |
| 49 | one is to merge updates from 'B project'. |
| 50 | |
| 51 | Comparing 'subtree' merge with submodules |
| 52 | ----------------------------------------- |
| 53 | |
| 54 | - The benefit of using subtree merge is that it requires less |
| 55 | administrative burden from the users of your repository. It works with |
| 56 | older (before Git v1.5.2) clients and you have the code right after |
| 57 | clone. |
| 58 | |
| 59 | - However if you use submodules then you can choose not to transfer the |
| 60 | submodule objects. This may be a problem with the subtree merge. |
| 61 | |
| 62 | - Also, in case you make changes to the other project, it is easier to |
| 63 | submit changes if you just use submodules. |
| 64 | |
| 65 | Additional tips |
| 66 | --------------- |
| 67 | |
| 68 | - If you made changes to the other project in your repository, they may |
| 69 | want to merge from your project. This is possible using subtree -- it |
| 70 | can shift up the paths in your tree and then they can merge only the |
| 71 | relevant parts of your tree. |
| 72 | |
| 73 | - Please note that if the other project merges from you, then it will |
| 74 | connect its history to yours, which can be something they don't want |
| 75 | to. |