We have a single git repo with 4 c++ projects which share a lot of source code files. These are our git branches:
master
: used for the main development (currently working on proj2 version 4.x)backports/proj1_4.x
: branched-out from master when we released the proj1 version 4.0, it contains bugfixes and was used for releasing versions 4.1, 4.2backports/proj2_3.x
: same for proj2, version 3.xbackports/proj3_2.x
: ...backports/proj4_2.x
: ...
When we fix a bug in master, we cherry-pick the fix to all backport branches. Having a single clone of the repository means that every time we switch between those branches, lots of c++ object files need to be recompiled.
Existing solutions
- multiple full clones
- checkout a different branch in each clone.
- requires a lot of disk space (our .git folder has ~700MB), but avoids switching between branches and therefore also the recompilation of object files. This may be the simplest solution.
- single clone with pre and post checkout git hooks for storing and restoring object files or timestamps of source files: https://stackoverflow.com/a/3195312/1341914
- git worktree
- use a single
.git
folder for multiple repository folders. - Warning: unusable with submodules as of Q2/2020: https://git-scm.com/docs/git-worktree#_bugs, but I'm not sure what does "Multiple checkout" mean.
- use a single
- ccache
- when working on master for a long time, the cache dir may contain only object files from master, because the older object files from backport branches didn't fit in the ccache storage limit.
- full clone of master + shallow clones of backport branches
- how would we cherry-pick a commit when the clone has just depth 1? The commit SHA1 wouldn't be found in the shallow clone, but we could export the commit as a patch file and then apply it to the shallow clone
- shared / reference
git clone --reference DIR GIT_REPO_URL
orgit clone --shared DIR
- because the parent repo doesn't know about its other clones, when an object is removed in the main repo, it may become unreferenced in the child repo, potentially corrupting the child repo.
What would you recommend? Is there any other/better solution?