Monorepo First, Submodules Later
When starting a new side-project I always wonder if parts of the codebase can be shared as an open-source project. A library extracted from the project might be of interest to other developers and it’s nice to have good stuff on your Github profile.
That possibility may compel you to spend a lot of time thinking about the repository structure. You may create a git submodule for every library that doesn’t exist yet but might be useful to you in other projects or to other people and you don’t want to lose the git history of that code. Trying to predict what is shareable before anything is done is almost impossible. When starting a project we have to try to do the minimum amount of metawork possible. There’s a solution to this problem that won’t require that much of upfront planning.
I start everything as monorepo and use git filter-branch to extract folders as separate repos if necessary (e.g. I want to extract a lib)
— Felipe O. Carvalho (@_Felipe) July 10, 2017
Don’t introduce any first-party git submodule in the beginning. Make sure things are cleanly separated in directories and get started.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Now you may notice that you have a directory with cool data structures that you
want to extract and publish as a library. You can create a new repository that
contains only that directory and commits that touch it using git
filter-branch
. Here’s how I did it for a project of mine.
To start, I made a copy of the repository to a new directory called
foc_libraries
.
1 2 3 |
|
This new repository will be the repository of the library based on the foc
in chronos. I use git filter-branch
on master to filter out anything
that’s not in the original foc
directory.
1 2 3 |
|
git filter-branch
removed all the commits that weren’t related to the foc
directory and the foc_libraries
repository now contains only the files from
the original foc
directory in chronos.
1 2 3 4 5 6 7 8 9 10 |
|
The commit log of foc_libraries
doesn’t have any commit related to the
original application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Now I can upload foc_libraries
to
Github.
1 2 3 4 5 6 7 8 9 10 11 |
|
After publishing the foc_libraries
repository I can go back to chronos
and
replace the foc
directory with a git submodule.
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Some adaptations might be needed on both repositories, but that’s pretty much all there is to it. Happy gitting!