git submodule Olaf Alders firstname.lastname@example.org/wundercounter Toronto Perl Mongers Sept 29, 2011
What does it do?Gits submodule support allows a repository to contain, as a subdirectory, a checkout of an external project.Submodules maintain their own identity; the submodule support just stores the submodule repository location andcommit ID, so other developers who clone the containing project ("superproject") can easily clone all thesubmodules at the same revision. Partial checkouts of the superproject are possible: you can tell Git to clone none,some or all of the submodules.source: "Git Community Book"http://book.git-scm.com/5_submodules.html
Add a submodulegit submodule add https://github.com/twitter/bootstrap.git inc/bootstrapgit status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## new file: .gitmodules# new file: inc/bootstrapcat .gitmodules[submodule "inc/bootstrap"]path = inc/bootstrapurl = https://github.com/twitter/bootstrap.gitgit commit -a -m "adds bootstrap as submodule"
Link it up!mkdir root/static/cssmkdir root/static/jsln -s inc/bootstrap/bootstrap.min.css root/static/css/ln -s inc/bootstrap/js root/static/js/bootstrapgit commit root -m "adds bootstrap symlinks"
Now what? ● Work as you normally would ● Later, when you want to update bootstrap to the latest versioncd inc/bootstrapgit pull origin mastercd ../..git commit inc/bootstrap -m "updates bootstrap"
Cloning repos with submodulesWhen someone else clones your repo, they need to update and init:$ cd ..git clone shiny_app bootstrapperCloning into bootstrapper...done.$ cd bootstrapper/$ lsREADME inc rootolaf-alderss-macbook-pro:bootstrapper olaf$ ls inc/bootstrap/# no output above -- the inc/bootstrap folder is empty
Remember to init and updateWeve got the repo, but the submodule is empty. Two commands will fix that.$ git submodule initSubmodule inc/bootstrap (https://github.com/twitter/bootstrap.git) registeredfor path inc/bootstrap$ git submodule updateCloning into inc/bootstrap...remote: Counting objects: 3845, done.remote: Compressing objects: 100% (1430/1430), done.remote: Total 3845 (delta 2474), reused 3663 (delta 2329)Receiving objects: 100% (3845/3845), 1.04 MiB | 388 KiB/s, done.Resolving deltas: 100% (2474/2474), done.Submodule path inc/bootstrap: checked out28c770bf679e131cc030c3bc4a1981450f831908
Is your HEAD detached?By default, the submodule in the cloned repo will not be on abranch:cd inc/bootstrap/git branch* (no branch) masterTry to remember to work on a branch before committing:$ git checkout master
Oops!If you commit while not on a branch, youll get the following "detached HEAD"message:$ git commit README.md -m "random change"[detached HEAD b92b798] random change 1 files changed, 3 insertions(+), 0 deletions(-)This is easy to recover from. Just check out a branch and merge the commit:$ git checkout master$ git merge b92b798
git pull != git submodule updateTeam members should remember to change their workflow to:git pull origin mastergit submodule updateRemember, a pull does not fetch submodule updates. To staytotally in sync, team members will want to update submodulesas they pull.
CaveatMerge conflictsIf two team members commit the same submodule withdiffering HEADs, you will get a merge conflict. You will need toresolve this manually.
What do you gain from submodules? ● You can build and test against bleeding edge checkouts ● You dont have to add someone elses code to your repo ● Team members can build against exactly the checkout youve built and tested against and vice versa ● Updating your submodules is trivial