How to use submodules publicly, but symlinks to a single clone locally?

(Appreciate the other advice, but answering with what I've decided to do, because it's easiest.)

Put clones of the submodules you are planning to share in their own directories.

Then set things up how you like in the using projects, each with their own clone of the submodule(s) you are planning to share. Once the projects are set up in a way that new users would get the submodules normally, replace the submodule directories with shared symbolic links to your single local instance where you do your edits, and add them to the .gitignore.

(Rather than just deleting the submodule-based directories, you might want to rename them out of the way. You could then move them back into place and pull them if necessary.)

So the working style is to just never commit the submodule / typechange. As long as you're willing to always track the master branch, people cloning the project will still get the right thing. Meanwhile, you can work with the single repository on your disk.

For projects at a more advanced stage, @VonC probably has the right answer... to not lie to Git, check in the submodules at the appropriate states, and use triggers to manage the updates.


So Git apparently sees the fact that it's a symbolic link, instead of following through to the directory.

Yes, Git would see such a change, because that submodule is declared in the parent repo as a special entry in the index.

Making a symlink would replace that special entry by a file of another type.

What you could do is try playing with GIT_WORK_TREE (as in "Including submodules in git checkout to GIT_WORK_TREE in hook").

But a more simpler solution would be to:

  • keep your submodule right where they are.
  • add another clone of that submodule repo where you want it (/path/to/sub).
  • detect any changes from the original submodule folder with a git --work-tree=/path/to/sub status from within your duplicated submodule folder in your parent repos.

Since it hasn't been mentioned before.
One could also override local tracking logic for specific git entry.

git update-index --assume-unchanged path/to/submodule

This will ignore any local changes to single file and works with submodules (as submodule is not treated as directory by git).

If needed, one can also simply re-enable local tracking again.

git update-index --no-assume-unchanged path/to/submodule

This solution scales nicely for multiple submodules in separate directory, as one could setup script to enable/disable exclusion of entire submodules directory, like mentioned in this answer.


You can bind mount the submodule's other directory

sudo mount --bind /path/to/main/repo relative/path/to/submodule

I can't find much info about this method, but saw it listed in this, similar question.