Why Mono-repo Might Save Our Bacon
When I first heard about Mono-repo from Duncan Hunter, I thought it was an insane idea. And even then I didn't care that much, I guess I had my plate full and didn't really have time to think it through. But I should have actually.
We started this big project several months ago and we had and still have plenty of challenges, but before getting to the pain, here are some points about it:
- We've got about 10 devs on and off
- We're following the Gitflow workflow, creating feature branches and so on.
- Microservices architecture to an extent
- Multiple git repositories
A bit of the pain:
- We have dependencies across projects in different repositories
- Very often changes will impact multiple repositories. So we often need to create branches for each of the repositories separately. And it's even more painful when it's time to submit a pull request: we have to create multiple of them and they have to be approved simultaneously
- Projects will often break locally when someone makes changes to a dependency and we get out of sync between the dependency and dependent project.
- We created some NuGet packages for some of our common libraries, which is great, but highly painful when you want to consume the library from the same set of projects, as we needed to publish the package even before using it.
We decided then to take a leap of faith and merge all our repositories to a single and mighty MonoRepo. One of our main concerns was to lose the commit history, but even that wouldn't be such a great deal since we would still have the history in the separate repositories.
JK put together a script to do the whole merge and it worked beautifully, including the whole history for all repositories merged into one. Here's an example of it:
//STEP 1: creating a brand new repository locally
md MightyMonoRepo
cd MightyMonoRepo
git init
//STEP 2: bringing a new repository
git remote add r1 https://github.com/thiagospassos/MultiRepoService1.git
git merge r1/master --allow-unrelated-histories
git remote rm r1
//STEP 3: optionally, you can use the mv command to move to subdirectory
md Service1
git mv MultiRepoService1.csproj Service1
git mv Program.cs Service1
You can now add as many repositories as you want, just by following the Steps 2 and 3. In my example, here's how the commit history looks:
And there it is. All the pain described before is gone, the only thing we need to do is configure the build server not to trigger a build with every commit, but only when there's a change in some especific folder. In this case, we're using TeamCity and it's quite simple to configure the trigger rules.
Let's see how much pain we are going to have by moving to Mono-repo, but I'm quite confident that whatever pain we have in the future is less than what we have now.
Hope it helps.
Cheers