Git submodules

Aus SDQ-Wiki

With git you can use so-called submodules to make a specific snapshot of a git repository part of another git repository. In contrast to svn externals, git submodules do not always include the most recent code from another repository but exactly the version you want.

You can read the section on submodules in the "Pro Git" book to understand what you can do with submodules. To work with submodules without understanding them, you can:

working with existing submodules

consuming submodule changes

pull upstream changes of submodules

To locally get all changes that were done in submodules:

git submodule update --remote

before producing submodule changes

checkout a branch for a submodule

Before you start to change something in a submodule you have to checkout a branch in the submodule folder:

git checkout branchOfSubmodule

(If you don't do this before changing stuff, then you have to merge with a branch as soon as you want to push local commits. Therefore, it's best to simply always checkout directly after cloning a submodule.)

prosuming submodule changes

change and commit in submodules

As usually.

merge submodule changes before committing and pushing them
git submodule update --remote --merge

(If you want to rebase instead of merging, you should read the section on submodules in the "Pro Git" book!)

add and commit submodule changes (local or pulled)

As stated in the intro, git submodules have an important advantage over svn externals. This great power also comes with an additional responsibility: As long as you don't tell git that you want your repository to depend on a new version of a submodule it will keep the old version. This means that pulling submodule updates only affects your local copy.

To tell git that changes in the submodules (no matter whether you committed them locally or pulled) should be part of the repository that you are working, you have to add and commit these changes. For this, you simply add the submodule folder to your index like any other folder that contains changes that you want to commit:

git add pathToSubmodule

Then, you commit this in order to tell git that you want your repository to work with this version of the submodule:

git commit

As long as you don't do this the repository will stay with the old versions of the submodules (even if your copy "works" with the new version).

pushing submodule changes

Before you push any changes to code that depends on your locally committed changes in a submodule, you should push these submodule changes to the remote. To do this automatically for all submodules of a repository (instead of pushing each submodule manually before pushing the repository) you can:

git push --recurse-submodules=on-demand

adding and removing submodules

adding a submodule

git submodule add http://uri.of.the.repo.to.be.added optionalFolderName

will add the repository as a submodule. You have to add and commit the resulting submodule folder and the .gitmodules file that was automatically created / updated.

removing a submodule

After deinitializing the submodule:

git submodule deinit -f -- path/to/submodule

and removing its folder:

git rm -f path/to/submodule

you are done. (If no submodule remains you may want to remove the empty ".gitmodules" file as well.)