Git Submodules Cheat Sheet

(Pssst. Check out Your Git Submodule and You for more in-depth information.)

What you should know

  • Submodules are a convenient way of putting a clone of another repository as a subdirectory within your main repository. The submodule is its own repository, and you can commit, branch, merge, etc. from inside it, just as with any other repository.
  • A submodule’s contents aren’t stored in the main repository – the main repository stores only the URL and SHA1 hash referring to a commit in the submodule repository. It’s only on your local computer that the submodule files are in a subdirectory of your main repository.
  • Unlike svn:externals, submodules point to a specific commit in the other repository, not a branch (whose code can change). Someone who clones your main repository next week will get the correct submodule code, even if the submodule has new commits upstream.
  • That means if you want to point to a different (newer) submodule commit, you must make a commit in your main repository to update the reference.
  • You cannot include only part of the other repository (e.g. one directory) as a submodule. You must include the entire other repository. Plan your repositories accordingly.

Recipes

Note: the [main]$ bits on each line represents your bash prompt. You should only type the stuff after the $.

  • Set up the submodule for the first time:
    [~]$  cd ~/main/
    [main]$  git submodule add git://github.com/my/submodule.git ./subm
    [main]$  git submodule update --init
    [main]$  git commit ./submodule -m "Added submodule as ./subm"
  • Fetch submodules after cloning a repository:
    [~]$  git clone git://github.com/my/main.git ~/main
    [~]$  cd ~/main/
    [main]$  git submodule update --init
  • Pull upstream main repo changes and update submodule contents:
    [main]$  git pull origin/master
    [main]$  git submodule update
  • Pull upstream changes to the submodule:
    [main]$  cd ./subm
    [subm]$  git pull origin/master   # or fetch then merge
    [subm]$  cd ..
    [main]$  git commit ./subm -m "Updated submodule reference"
  • Edit and commit files in your submodule:
    [main]$  cd ./subm
    [subm]$  edit whatever.rb
    [subm]$  git commit whatever.rb -m "Updated whatever.rb"
    [subm]$  cd ..
    [main]$  git commit ./subm -m "Updated submodule reference"
  • Push your submodule changes to the submodule upstream:
    [main]$  cd ./subm
    [subm]$  git push origin master