Mono-repo or multi-repo? Why choose one, when you can have both?

Many are still debating “mono-repo” or “multi-repo”. For those of you who have no idea what a mono or multi repo is, I’m referring the the organization of your repositories. Traditionally, there have been two camps, with supporters on both sides on the aisle.

Mono-repos are a source control pattern where all of the source code is kept in a single repository. This makes it super simple to get all of your employees access to everything in one shot. Just clone it down, and done. Multi-repos on the other hand, refers to organizing your projects each into their own separate repositories.

I was surprised when I learned that Google, one of the most advanced technology companies in the world, uses a monorepo. I was used to making many repositories, one for each of my services, and with good reason.

  1. I hire contractors frequently, and giving them access to ALL of the source code doesn’t make sense, and isn’t secure. Having multiple repositories makes it easy to give access to subsets of repositories on a “need to code” basis.
  2. I set up Continuous Deployment for my projects. It’s much easier to let each repository have it’s own process for being deployed. When using a mono-repo, there needs to be additional logic for sorting through the directories that make up the different projects within the mono-repo.

For me, it seems obvious, but, what happens when you get to 10 different repositories.. 20? 50? 100? more? It gets very difficult to manage. No one wants to git clone a whole bunch of different repositories one at a time.

I’m not the first to encounter this issue, and from the struggle emerged a (now defunct) tool called gitslave. Gitslave provided a new command gits which could be used just like git, except across many directories at once. The “meta-repo” was born. And today, thanks to Matt Walters, there is a new, even simpler choice: meta.

Meta is a plugin-powered tool whose purpose is to make building distributed systems/libraries/codebases easier. It does so by providing commands which can be executed against any number of projects in your solution at once. Need to create a branch on five projects at once?

meta git checkout -b feature/my-new-branch

Want to commit all changes for the feature you are working on the spans several services?

meta git commit -m 'made the feature'

meta will loop through the projects you’ve added to your .meta file, and apply the command to each of them. However, meta works for much more than just git. In fact, all meta really does, is organize your projects into a JSON file, and provide an extensible core for easily providing new functionality through plugins. meta ships with a few plugins built into the core, and more are available from the community.

Below I will walk you through the simple process of creating your first meta-repo.

Making a `meta` repository

First, let’s install meta.

npm i -g meta

Then, let’s create a new meta-repository.

mkdir yourProject && cd yourProject
meta init

This creates a .meta file with the following content.

{
"projects": {}
}

Next, head on over to GitHub and create a new repository and push our repo.

git init
git add -A
git commit -m “init meta repo”
git remote add origin git@github.com:you/yourProject.git
git push -u origin master

Adding projects to your meta repo

Now, all you need to do is add some projects, which is as simple as running the following command, provided by the meta-project plugin. Let’s imagine we have a few services we want to add: userService, graphqlService, and appService.

meta project add userService git@github.com:you/userService.git
meta project add graphqlService git@github.com:you/graphqlService.git
meta project add appService git@github.com:you/appService.git

The above will modify the .meta file and .gitignore file to look like the following:

// .meta
{
"projects": {
"userService": "git@github.com:you/userService.git",
"graphqlService": "git@github.com:you/graphqlService.git",
"appService": "git@github.com:you/appService.git"
}
}
// .gitignore
userService
graphqlService
appService

Commit, and push.

Sharing

Now, when you have a new developer to onboard, you can simply give them access to an appropriate meta-repo. You can make many meta-repos if you’d like. One for DevOps related projects, one with everything for an admin, one with just services for a backend engineer, or even a meta repo full of other meta repos. Slice it any way you’d like!

To clone a meta repo, simply run the following:

meta git clone git@github.com:you/yourProject.git

To sync the additional repos defined in the .meta file, run:

meta git update

Conclusion

When asked multi-repo or mono-repo, my answer is usually “meta”.

If you are interested in how to build your own meta plugin, check out my other post “Developing a plugin for meta”.

Interested in hearing MY DevOps Journey, WITHOUT useless AWS Certifications? Read it now on HackerNoon!