03 Workshops as submodules - harvardinformatics/informatics-website GitHub Wiki

We now host our workshops in individual repositories that we include on the website as submodules, which are git repositories embedded within a repository. After working with these for a bit, it seems that they are fully functional as individual repos within the website repo. Once set-up, I can enter the submodule folder, make changes, and commit and push back to the submodule repo. Then when I exit the submodule directory (cd ..), I am back in the main website repo and see the changes reflected in the submodule as (new commits), which I must commit and push back to the website repo.

Submodule locations

The submodules are located in docs/workshops/:

tree docs/workshops/
├───biotips
├───healthy-habits
├───intro-r
├───python-intensive
└───short-trainings

Though you'll notice if you check this path on GitHub, the links point to specific commits in each repository. This is normal.

Initializing submodules

Submodules aren't automatically added to your local repository if you clone/pull from remote. Depending on whether or not you just cloned the website repository, you must do one of the following to obtain them:

1. Cloning

If you are cloning the website repository for the first time and want to also get the submodules, just as --recurse-submodules to the command:

git clone --recurse-submodules <repo-url>

2. Initializing submodules in a repository you've already cloned

In the case that you already have a local copy of the website repository and want to get the submodules, use the following:

git submodule update --init --recursive

This should populate the docs/workshops/ folder.

Adding a submodule

If we need to add a new workshop submodule, first create the workshop repository separately. Then, in your local copy of the website repository:

git submodule add <workshop-repo-https-url> <submodule-path-in-website-repo>

For example, if I make a new workshop repository called my-workshop, I would do:

git submodule add https://github.com/harvardinformatics/my-workshop.git docs/workshops/my-workshop/

The URL is the same one you would use to clone the workshop repository with https. The submodule path is where in the website repo the submodule will be stored.

Important: The repository URL must be the https URL for the submodule pages to appear on the website.

Important: The workshop repository must be public for the submodule pages to appear on the website.

After you have run git submodule add, you will need to commit and push those changes to remote so the submodule is included there as well.

Submodule quirks

I've run into a few weird behaviors that may make more sense as I use these submodules more. Until then, I'm collecting a list here.

  1. Empty submodule folders after pulling

    It has occurred multiple times, especially when pulling on a different machine than the one on which I made changes, that the submodule folders will appear empty afterwards. In this case, running

    git submodule update --init --recursive

    again seems to resolve this.

  2. Not on main branch when making changes in a submodule

    Initially, the submodules are included in a detached HEAD state. If you try to make changes or commits in this state and then push them back to the submodule, it will fail. You have to explicitly switch to the main branch to push changes back to the submodule:

    git checkout main

    ⚠️ Warning: If you make changes/commits and then realize you are on a detached HEAD and checkout main, you may lose your changes/commits.

  3. Submodules not up to date with latest changes

    In this case, a simple git pull from within the submodule folder should fix this, though I have found myself in a detached HEAD state sometimes after pulling...

Various other submodule commands that may be useful at some point

1. Update submodule to the latest commit from its remote

git submodule update --remote <submodule-path> 

2. Remove a submodule

git submodule deinit -f -- <submodule-path>
git rm -f <submodule-path>
rm -rf .git/modules/<submodule-path>
⚠️ **GitHub.com Fallback** ⚠️