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.
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:
- 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)
- repos containing submodules see them as a simple text file with a submodule repo name and a specific commit number.
- When you
cdinto 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.