Skip to content

Instantly share code, notes, and snippets.

Created May 27, 2013 17:05
Show Gist options
  • Save atomkirk/5658102 to your computer and use it in GitHub Desktop.
Save atomkirk/5658102 to your computer and use it in GitHub Desktop.
Submodule notes

To a parent project, a submodule is essentially a subdirectory in your project that is viewed by the parent repo as a simple text file with a name and a commit number. So, when you pull down a project that uses submodules:

git submodule add <path to repo>

It will add that sub directory and an entry to its .gitmodules file (with the name and commit number). So when you git add . and git commit -am 'message' in the parent repo, the only thing you are adding and committing is the current commit of the submodule.

The git submodule command is how to work beyond this narrow view of a text file with a commit message. As shown above, you would use git submodule add <path to repo> to ADD it, but all you're adding is the text file with a name and commit. To actually pull down the files, you would run:

git submodule update --init --recursive

This will cause the actual subdirectories to contain the contents of the commit the parent project points to in that text file with a module name and commit number. It will initialize any submodules that are not initialized and it will recursively update all sub-sub-submodules, etc.

Now you can navigate down into submodules and work with them as their own repo, without any side effects on the parent. Once you've changed the submodule, added a new commit, you must then cd .. into the parent project and git add . git commit -am 'updating submodules' so the new commit of the submodule will be recorded in the parent's text file representing the submodule.

When you are sharing a project between to parent projects, and you make a bunch of changes to submodules in the other project (let's say an iOS app) and then you switch to the mac app, you can run:

git pull --recurse-submodules

and it will pull the latest from the parent and all the submodules.

So that's how it's done. Just remember these simple concepts:

  1. each submodule is it's own repo, with it's own history, etc. (It might as well be in its own directory somewher else on disk)
  2. repos containing submodules see them as a simple text file with a submodule repo name and a specific commit number.
  3. When you cd into a submodule and add commits, make sure you cd .. into the parent and add a commit that records the new commit number for the submodule.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment