In fact, for at least one of our components, we've already done this. We had something that solved the same problem for a couple of different permutations of software versions and platforms. The person who had originally written it had used separate repos, with common code copied and pasted between them, and later on we merged the repos together and factored out the common code so that could be shared. So we already have at least one repo which has 4 root commits, I believe.
Actually, I just checked and it has 7 root commits. I'd forgotten that we had also had similar problems that needed to be solved for some other software, and had some interns who had done those in separate repos as well, which also eventually got merged in to share all of the common code:
$ git log --max-parents=0 --pretty="format:%h %cd %s" --date=short
666c0bf 2012-07-09 Initial tree.
528ca3a 2012-06-12 first commit
50f1b18 2012-06-12 first commit
86d66e0 2011-11-17 initial
76a7789 2011-03-21 initial commit
58f7afc 2010-05-20 initial
deb50b7 2009-10-29 initial commitIt makes for a great conversation piece, even around non-tech crowds.
Has been particularly interesting to balance the different languages in the same repo. Few painful bits, but overall has worked out really well.
We also build the entire thing into a single Docker container containing every service. You just start the particular one you want via the command (the entrypoint is a little shell script to invoke the correct executable).
Otherwise if you ever need to do a rollback or post mortem or similar you have to figure out what commit out of the 20 different projects was actually being used at the time.
Of course that comes at a cost and there are other ways to get the same benefit, but my experience is that this is an easy way to keep things consistent.
- much less admin, don’t need to maintain/update so many repos
- easier to coordinate changes between systems at the same time
- everything is on a single version of each library - you don’t have some services on one version, some on another, etc
Benefits of having a single Docker image:
- much faster (overall) build times - doing everything in one go is way faster than doing each one individually
- much faster deployment - only have to download the image once per host, rather than many variations
- most services have a similar set of the same base dependencies, so reduces duplication
- overall the difference in image size between including one service and including all of them is probably only 5-10MB anyway
Those are just the things which immediately come to mind. There are probably many others.
Image layers are immutable and get deduplicated/cached individually when stored or sent over the network. For example if you pull 10 images with a common base to the same host, the first image might be slow to download but after that docker only fetches the deltas between it and the rest.
When it came time to pull things together, we thought it'd be fun to try and maintain the histories. So I added his repo as a remote and simply merged his unrelated history into mine.
Fast forward and now we offer hoodies as swag to anyone who contributes to the repo. We personalize the hoodie with your git username, the truncated commit hash of your first commit, and the number of parent commits to your first commit.
Having 2 root commits means that both my cofounder and I have hoodies with a large 0 as number of parent commits. Just a nice way to commemorate this accident of history :)