|
| 1 | +git-subtree(1) |
| 2 | +============== |
| 3 | + |
| 4 | +NAME |
| 5 | +---- |
| 6 | +git-subtree - add, merge, and split subprojects stored in subtrees |
| 7 | + |
| 8 | + |
| 9 | +SYNOPSIS |
| 10 | +-------- |
| 11 | +[verse] |
| 12 | +'git subtree' add --prefix=<prefix> <commit> |
| 13 | +'git subtree' merge --prefix=<prefix> <commit> |
| 14 | +'git subtree' pull --prefix=<prefix> <repository> <refspec...> |
| 15 | +'git subtree' split --prefix=<prefix> <commit...> |
| 16 | + |
| 17 | + |
| 18 | +DESCRIPTION |
| 19 | +----------- |
| 20 | +git subtree allows you to include an subproject in your |
| 21 | +own repository as a subdirectory, optionally including the |
| 22 | +subproject's entire history. For example, you could |
| 23 | +include the source code for a library as a subdirectory of your |
| 24 | +application. |
| 25 | + |
| 26 | +You can also extract the entire history of a subdirectory from |
| 27 | +your project and make it into a standalone project. For |
| 28 | +example, if a library you made for one application ends up being |
| 29 | +useful elsewhere, you can extract its entire history and publish |
| 30 | +that as its own git repository, without accidentally |
| 31 | +intermingling the history of your application project. |
| 32 | + |
| 33 | +Most importantly, you can alternate back and forth between these |
| 34 | +two operations. If the standalone library gets updated, you can |
| 35 | +automatically merge the changes into your project; if you |
| 36 | +update the library inside your project, you can "split" the |
| 37 | +changes back out again and merge them back into the library |
| 38 | +project. |
| 39 | + |
| 40 | +Unlike the 'git submodule' command, git subtree doesn't produce |
| 41 | +any special constructions (like .gitmodule files or gitlinks) in |
| 42 | +your repository, and doesn't require end-users of your |
| 43 | +repository to do anything special or to understand how subtrees |
| 44 | +work. A subtree is just another subdirectory and can be |
| 45 | +committed to, branched, and merged along with your project in |
| 46 | +any way you want. |
| 47 | + |
| 48 | +In order to keep your commit messages clean, we recommend that |
| 49 | +people split their commits between the subtrees and the main |
| 50 | +project as much as possible. That is, if you make a change that |
| 51 | +affects both the library and the main application, commit it in |
| 52 | +two pieces. That way, when you split the library commits out |
| 53 | +later, their descriptions will still make sense. But if this |
| 54 | +isn't important to you, it's not *necessary*. git subtree will |
| 55 | +simply leave out the non-library-related parts of the commit |
| 56 | +when it splits it out into the subproject later. |
| 57 | + |
| 58 | + |
| 59 | +COMMANDS |
| 60 | +-------- |
| 61 | +add:: |
| 62 | + Create the <prefix> subtree by importing its contents |
| 63 | + from the given commit. A new commit is created |
| 64 | + automatically, joining the imported project's history |
| 65 | + with your own. With '--squash', imports only a single |
| 66 | + commit from the subproject, rather than its entire |
| 67 | + history. |
| 68 | + |
| 69 | +merge:: |
| 70 | + Merge recent changes up to <commit> into the <prefix> |
| 71 | + subtree. As with normal 'git merge', this doesn't |
| 72 | + remove your own local changes; it just merges those |
| 73 | + changes into the latest <commit>. With '--squash', |
| 74 | + creates only one commit that contains all the changes, |
| 75 | + rather than merging in the entire history. |
| 76 | + |
| 77 | + If you use '--squash', the merge direction doesn't |
| 78 | + always have to be forward; you can use this command to |
| 79 | + go back in time from v2.5 to v2.4, for example. If your |
| 80 | + merge introduces a conflict, you can resolve it in the |
| 81 | + usual ways. |
| 82 | + |
| 83 | +pull:: |
| 84 | + Exactly like 'merge', but parallels 'git pull' in that |
| 85 | + it fetches the given commit from the specified remote |
| 86 | + repository. |
| 87 | + |
| 88 | +split:: |
| 89 | + Extract a new, synthetic project history from the |
| 90 | + history of the <prefix> subtree. The new history |
| 91 | + includes only the commits (including merges) that |
| 92 | + affected <prefix>, and each of those commits now has the |
| 93 | + contents of <prefix> at the root of the project instead |
| 94 | + of in a subdirectory. Thus, the newly created history |
| 95 | + is suitable for export as a separate git repository. |
| 96 | + |
| 97 | + After splitting successfully, a single commit id is |
| 98 | + printed to stdout. This corresponds to the HEAD of the |
| 99 | + newly created tree, which you can manipulate however you |
| 100 | + want. |
| 101 | + |
| 102 | + Repeated splits of exactly the same history are |
| 103 | + guaranteed to be identical (ie. to produce the same |
| 104 | + commit ids). Because of this, if you add new commits |
| 105 | + and then re-split, the new commits will be attached as |
| 106 | + commits on top of the history you generated last time, |
| 107 | + so 'git merge' and friends will work as expected. |
| 108 | + |
| 109 | + Note that if you use '--squash' when you merge, you |
| 110 | + should usually not just '--rejoin' when you split. |
| 111 | + |
| 112 | + |
| 113 | +OPTIONS |
| 114 | +------- |
| 115 | +-q:: |
| 116 | +--quiet:: |
| 117 | + Suppress unnecessary output messages on stderr. |
| 118 | + |
| 119 | +-d:: |
| 120 | +--debug:: |
| 121 | + Produce even more unnecessary output messages on stderr. |
| 122 | + |
| 123 | +--prefix=<prefix>:: |
| 124 | + Specify the path in the repository to the subtree you |
| 125 | + want to manipulate. This option is currently mandatory |
| 126 | + for all commands. |
| 127 | + |
| 128 | + |
| 129 | +OPTIONS FOR add, merge, AND pull |
| 130 | +-------------------------------- |
| 131 | +--squash:: |
| 132 | + Instead of merging the entire history from the subtree |
| 133 | + project, produce only a single commit that contains all |
| 134 | + the differences you want to merge, and then merge that |
| 135 | + new commit into your project. |
| 136 | + |
| 137 | + Using this option helps to reduce log clutter. People |
| 138 | + rarely want to see every change that happened between |
| 139 | + v1.0 and v1.1 of the library they're using, since none of the |
| 140 | + interim versions were ever included in their application. |
| 141 | + |
| 142 | + Using '--squash' also helps avoid problems when the same |
| 143 | + subproject is included multiple times in the same |
| 144 | + project, or is removed and then re-added. In such a |
| 145 | + case, it doesn't make sense to combine the histories |
| 146 | + anyway, since it's unclear which part of the history |
| 147 | + belongs to which subtree. |
| 148 | + |
| 149 | + Furthermore, with '--squash', you can switch back and |
| 150 | + forth between different versions of a subtree, rather |
| 151 | + than strictly forward. 'git subtree merge --squash' |
| 152 | + always adjusts the subtree to match the exactly |
| 153 | + specified commit, even if getting to that commit would |
| 154 | + require undoing some changes that were added earlier. |
| 155 | + |
| 156 | + Whether or not you use '--squash', changes made in your |
| 157 | + local repository remain intact and can be later split |
| 158 | + and send upstream to the subproject. |
| 159 | + |
| 160 | + |
| 161 | +OPTIONS FOR split |
| 162 | +----------------- |
| 163 | +--annotate=<annotation>:: |
| 164 | + When generating synthetic history, add <annotation> as a |
| 165 | + prefix to each commit message. Since we're creating new |
| 166 | + commits with the same commit message, but possibly |
| 167 | + different content, from the original commits, this can help |
| 168 | + to differentiate them and avoid confusion. |
| 169 | + |
| 170 | + Whenever you split, you need to use the same |
| 171 | + <annotation>, or else you don't have a guarantee that |
| 172 | + the new re-created history will be identical to the old |
| 173 | + one. That will prevent merging from working correctly. |
| 174 | + git subtree tries to make it work anyway, particularly |
| 175 | + if you use --rejoin, but it may not always be effective. |
| 176 | + |
| 177 | +-b <branch>:: |
| 178 | +--branch=<branch>:: |
| 179 | + After generating the synthetic history, create a new |
| 180 | + branch called <branch> that contains the new history. |
| 181 | + This is suitable for immediate pushing upstream. |
| 182 | + <branch> must not already exist. |
| 183 | + |
| 184 | +--ignore-joins:: |
| 185 | + If you use '--rejoin', git subtree attempts to optimize |
| 186 | + its history reconstruction to generate only the new |
| 187 | + commits since the last '--rejoin'. '--ignore-join' |
| 188 | + disables this behaviour, forcing it to regenerate the |
| 189 | + entire history. In a large project, this can take a |
| 190 | + long time. |
| 191 | + |
| 192 | +--onto=<onto>:: |
| 193 | + If your subtree was originally imported using something |
| 194 | + other than git subtree, its history may not match what |
| 195 | + git subtree is expecting. In that case, you can specify |
| 196 | + the commit id <onto> that corresponds to the first |
| 197 | + revision of the subproject's history that was imported |
| 198 | + into your project, and git subtree will attempt to build |
| 199 | + its history from there. |
| 200 | + |
| 201 | + If you used 'git subtree add', you should never need |
| 202 | + this option. |
| 203 | + |
| 204 | +--rejoin:: |
| 205 | + After splitting, merge the newly created synthetic |
| 206 | + history back into your main project. That way, future |
| 207 | + splits can search only the part of history that has |
| 208 | + been added since the most recent --rejoin. |
| 209 | + |
| 210 | + If your split commits end up merged into the upstream |
| 211 | + subproject, and then you want to get the latest upstream |
| 212 | + version, this will allow git's merge algorithm to more |
| 213 | + intelligently avoid conflicts (since it knows these |
| 214 | + synthetic commits are already part of the upstream |
| 215 | + repository). |
| 216 | + |
| 217 | + Unfortunately, using this option results in 'git log' |
| 218 | + showing an extra copy of every new commit that was |
| 219 | + created (the original, and the synthetic one). |
| 220 | + |
| 221 | + If you do all your merges with '--squash', don't use |
| 222 | + '--rejoin' when you split, because you don't want the |
| 223 | + subproject's history to be part of your project anyway. |
| 224 | + |
| 225 | + |
| 226 | +AUTHOR |
| 227 | +------ |
| 228 | +Written by Avery Pennarun < [email protected]> |
| 229 | + |
| 230 | + |
| 231 | +GIT |
| 232 | +--- |
| 233 | +Part of the linkgit:git[1] suite |
0 commit comments