The good and the bad of git subtree
(mostly the good).
NAME git-subtree - Merge subtrees together and split repository into subtrees SYNOPSIS git subtree add -P <prefix> <commit> git subtree add -P <prefix> <repository> <ref> git subtree pull -P <prefix> <repository> <ref> git subtree push -P <prefix> <repository> <ref> git subtree merge -P <prefix> <commit> git subtree split -P <prefix> [OPTIONS] [<commit>] ... snip ... DESCRIPTION Subtrees allow subprojects to be included within a subdirectory of the main project, optionally including the subproject’s entire history. For example, you could include the source code for a library as a subdirectory of your application. Subtrees are not to be confused with submodules, which are meant for the same task. Unlike submodules, subtrees do not need any special constructions (like .gitmodule files or gitlinks) be present in your repository, and do not force end-users of your repository to do anything special or to understand how subtrees work. A subtree is just a subdirectory that can be committed to, branched, and merged along with your project in any way you want. ... snip... OPTIONS -q, --quiet Suppress unnecessary output messages on stderr. -d, --debug Produce even more unnecessary output messages on stderr. -P <prefix>, --prefix=<prefix> Specify the path in the repository to the subtree you want to manipulate. This option is mandatory for all commands. -m <message>, --message=<message> This option is only valid for add, merge and pull (unsure). Specify <message> as the commit message for the merge commit.
The good:
git subtree
does not require users of your repository to learn anything new. They can ignore the fact that you are using git subtree to manage dependencies.git subtree
does not add new metadata files like git submodule does (i.e., .gitmodule).The bad:
$ git checkout -b subtree
The synopsis:
$ git subtree add -P <prefix> <repository> <ref>
The example:
$ git subtree add \ --prefix .vim/bundle/tpope-vim-surround \ https://bitbucket.org/vim-plugins-mirror/vim-surround.git \ master \ --squash git fetch https://bitbucket.org/vim-plugins-mirror/vim-surround.git master warning: no common commits remote: Counting objects: 338, done. remote: Compressing objects: 100% (133/133), done. remote: Total 338 (delta 101), reused 338 (delta 101) Receiving objects: 100% (338/338), 71.46 KiB | 46.00 KiB/s, done. Resolving deltas: 100% (101/101), done. From https://bitbucket.org/vim-plugins-mirror/vim-surround * branch master -> FETCH_HEAD Added dir '.vim/bundle/tpope-vim-surround' $
$ tree .vim .vim └── bundle └── tpope-vim-surround ├── doc │ └── surround.txt ├── plugin │ └── surround.vim └── README.markdown 4 directories, 3 files $
$ git log --oneline cc770c1 (HEAD -> subtree) Merge commit 'bd61f717bcc5d8569846d875952d6aefab987dd1' as '.vim/bundle/tpope-vim-surround' bd61f71 Squashed '.vim/bundle/tpope-vim-surround/' content from commit 02199ea ... snip ... $
Synopsis:
$ git subtree pull -P <prefix> <repository> <ref>
Example:
$ git subtree pull \ --prefix .vim/bundle/tpope-vim-surround \ https://bitbucket.org/vim-plugins-mirror/vim-surround.git \ master \ --squash $
Add a remote (-f
means fetch immediately):
$ git remote add \ -f \ tpope-vim-surround \ https://bitbucket.org/vim-plugins-mirror/vim-surround.git $
Add the subtree:
$ git subtree add \ --prefix .vim/bundle/tpope-vim-surround \ tpope-vim-surround \ master \ --squash $
To update at a later date:
$ git fetch tpope-vim-surround master $ git subtree pull \ --prefix .vim/bundle/tpope-vim-surround \ tpope-vim-surround \ master \ --squash $