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

4 Comments

  1. mahesh
    Posted 2012-06-21 at 00:19 | Permalink

    One suggestion:
    While committing in submodule first checkout to a branch then do commit.
    Without branch the push doesn’t do anything.
    See these links
    http://stackoverflow.com/questions/5814319/git-submodule-push
    http://stackoverflow.com/questions/4445738/unable-to-push-commits-from-a-git-submodule?rq=1

    Thanks,
    mahesh

  2. dave
    Posted 2012-12-12 at 17:31 | Permalink

    In the first recipe, shouldn’t the last line be:

    [main]$ git commit .gitmodules -m "Added submodule as ./subm"

  3. Mohsin Hijazee
    Posted 2013-04-05 at 12:34 | Permalink

    And if you want to update all the submodules of a project:

    $ git submodule foreach git pull origin master

  4. Posted 2013-04-06 at 02:43 | Permalink

    such a beautiful blog! I am wondering if I can use `git add` some files under submodule to parent repo

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>