submodules

Git submodules provide a way to consider any repository as a versioned "package" that can be included in any other git repo.

clone a repo that has submodules

    
        git clone --recurse-submodules -j8 git://github.com/foo/bar.git
    

Note: -j8 is an optional performance optimization that became available in version 2.8, and fetches up to 8 submodules at a time in parallel — see man git-clone

clone in repositories after cloning a repo

When you clone a repository git will not automatically clone in the contents of any submodules, but it will clone an empty directory with the name of that repository, in order to actually get the contents of those submodules you have to do the following

    
        git submodule init
        git submodule update
    
alternatively if you know that it recursively contains more submodules
    
        git submodule update --init --recursive
    

git pulling in submodules

Suppose you're in a submodule that contains more submodules, currently git status tells you that there are no changes at all, now you run git pull in that submodule and there are updates, namely the updates update the references to a few of the submodules, this can occur when someone has updated the versions of the submodules elsewhere and you are just getting those changes.

What usually appears is something like this:

    
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git restore ..." to discard changes in working directory)
        modified:   build_notifier (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

    

This may seem confusing, but just know that even though it says that there are changes, the changes are not from you editing files, its just that when you git pulled it changed the reference to the git submodule to the new version, and since your local version still contains the old copy, there is a diff being generated. To fix this run:

    
git submodule update
    

Don't read these command as magic incantations to solve all your problems, for further understanding run man git submodule

mistakes

ssh submodules, github organizations and collaborators

When adding submodules from an organization using ssh links, then there comes a problem that people who are not part of the organization will not be able to clone in submodules as they do not have access for ssh as only collaborators can do this (even with public repositories). One fix to this is to add people as collaborators to the organization, but eventually adding everyone to an organization just so they can clone in the submodules becomes a little unwieldy. Here's a way we can fix this:

HEAD detached from 54b9bf8

If you see that you are on a detached head, this means that you cannot commit any changes here, if you have uncommitted changes you can switch to main with git checkout main, if you do have committed changes then you have to do this:

    
git switch -c temp-work
git switch main
git merge temp-work
git branch -d temp-work
    

To avoid this problem in the future, we have to realize why this usually occurs, it happens when you clone a repository and initialize its submodules such as by doing git clone --recursive URL, it makes sense that git puts every submodule at its respective commit, this is so that you can have reproducible behavior when you clone in submodules, but sometimes you know what you want the most up-to-date version of a submodule, in that case run this after the fact:

    
        git submodule foreach --recursive git checkout main
    

edit this page