gitgit-submodules

Share a working tree with git submodules


Suppose I have a library Common that may be used stand-alone, and is used by projects P1 and P2, so the tree I want looks like

/Common/.git
        ...
/P1/.git
    .gitmodules  # points to remote server
    Common/
    ...
/P2/.git
    .gitmodules  # points to remote server
    Common/
    ...

When I make a change in /Common, I would like to be able to test it using P1 and P2 before committing. With the usual git submodule command set, I would have to commit from /Common, push to remote, then pull from both /P1/Common and /P2/Common. If the commit breaks something, it cannot be amended because the bad change has already been published. Alternatively, I could git remote add quicktest /Common from /P?/Common to be able to pull without touching the remote server. But this has lots of opportunities for inconsistency and it is dirty to strip broken commits from /P?/Common so that they can be amended in /Common.

I would rather that, during development, the working tree from /Common be used by P1 and P2, but I can't make /P1/Common a symlink to /Common because git submodule recognizes the symlink as different from a directory. Hardlinking directories is not allowed by most file systems. I can hardlink all the files using

rm -rf /P1/Common
cp -rl /Common /P1/Common

which works quite well until a new file is added to /Common in which case this process needs to be repeated. Is there an elegant way to both

  1. keep git clone --recursive git://remote/P1.git working for the end user, and
  2. allow me to easily test that changes in /Common work with P1 and P2?

Solution

  • I would rather establish an intermediate bare repo where to:

    At least, if commits are amended/removed later, that intermediate repo has never been published outside and you still can reset your P1/Common and P2/Common submodules to that intermediate repo content.


    Update: if you are using git worktree, since Git 2.5 (July 2015, 5 years after writing this answer), make sure to use Git 2.25 (Q1 2020).
    Before that, "git worktree add" internally calls "reset --hard", which affected submodules.