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

6 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

    • James Coleman
      Posted 2014-03-12 at 05:26 | Permalink

      Doesn’t that command (foreach git pull origin master) update each submodule to master of the external submodules? That master is probably ahead of what works (or is tested) with your project.

      I think this command will update each submodule in project to latest version comitted in your project:
      $ git submodule update –init

  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

  5. Trevor Hickey
    Posted 2014-01-29 at 00:26 | Permalink

    To get submodules automatically, you can use “git clone –recursive “

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>