Skip to content

Instantly share code, notes, and snippets.

@jywsn
Last active November 6, 2016 20:47
Show Gist options
  • Save jywsn/a9f884b290106be570893c0576afd927 to your computer and use it in GitHub Desktop.
Save jywsn/a9f884b290106be570893c0576afd927 to your computer and use it in GitHub Desktop.
About git submodules

Summarized from https://git-scm.com/book/en/v2/Git-Tools-Submodules

Adding a submodule

Add an existing Git repository as a submodule of the repository:

$ git submodule add <subproject-repo-url>

The default is to add the subproject into a directory named the same as the repository. Also creates a new .gitmodules file, which is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into:

[submodule "subproject-name"]
	path = <subproject-name>
	url = <subproject-repo-url>

Git sees the code in subproject-name as a submodule and doesn’t track its contents when you're not in that directory. Instead, Git sees it as a particular commit from that repository.

Cloning a project with submodules

When you clone a project with submodules, by default you get the directories that contain submodules, but none of the files within them. You need to initialize your local configuration file, and then fetch all the data from that project and check out the appropriate commit listed in your superproject:

$ git clone <superproject-repo-url>
$ git submodule init
$ git submodule update

Or you can clone with the --recursive flag, which will automatically initialize and update each submodule in the repository:

$ git clone --recursive <superproject-repo-url>

Pulling in submodule changes

To check for new work in a submodule:

$ cd <submodule-dir> # cd into submodule directory
$ git pull            # or fetch & merge

OR, you can do it the easy way, and let Git go into your submodules and fetch and update for you:

$ git submodule update --remote [<submodule-name>]

This command will by default assume that you want to update the checkout to the master branch of the submodule repository, but you can set this to something different if you want:

$ git config -f .gitmodules submodule.<submodule-name>.branch <branch-name>
$ git submodule update --remote

To see what changed:

$ cd <superproject dir>
$ git diff --submodule

Making changes to a submodule

We should just always make changes to the submodule in the repository for the submodule. Then we can avoid having to merge submodule changes when submodule histories have diverged and are committed to diverging branches in the superproject.

Potential Issues

If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory. But this just an annoyance and not really a problem.

If you switch from subdirectories to submodules (i.e. want to move tracked files in your project into a submodule), you have to unstage the directory before adding it as a submodule:

$ git rm -r <subdirectory>
$ git submodule add <subproject-repo-url>

If you then try to switch back to a branch that is still using the subdirectory instead of the submodule, then you should read all the info at the link above, because I don't wanna type it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment