10 ms·
My advice is that if components need to release together, then they ought to be in the same repo. I'd probably go further and say that if you just think compon
by curtis 8y ago
My advice is that if components need to release together, then they ought to be in the same repo. I'd probably go further and say that if you just think components might need to release together then they should go in the same repo, because you can in fact pretty easily manage projects with different release schedules from the same repo if you really need to.
On the other hand if you've got a whole bunch of components in different repos which need to release together it suddenly becomes a real pain.
If you've got components that will never need to release together, then of course you can stick them in different repositories. But if you do this and you want to share common code between the repositories then you will need to manage that code with some sort of robust versioning system, and robust versioning systems are hard. Only do something like that when the value is high enough to justify the overhead. If you're in a startup, chances are very good that the value is not high enough.
As a final observation, you can split big repositories into smaller ones quite easily (in Git anyway) but sticking small repositories together into a bigger one is a lot harder. So start out with a monorepo and only split smaller repositories out when it's clear that it really makes sense.
- forty 8y agoMy rule of thumb is: if you need to do PRs in several repositories to do one features, you should probably merge the repositories. At work, we have code spread among a bunch of repositories, and having to link to the 2/3 related PRs in other repos is a major PITA, and even more so for the reviewers.
- tigershark 8y agoNot always. It makes absolutely sense to have a repository for the gui and one for the server. When writing a new feature you usually write some gui code and some server code and create different pull requests. I think monorepos are seriously wrong and I completely agree with this article.
- Vinnl 8y agoWell... Why does that make sense? I have a repository containing both the GUI and the server, and sometimes I have to make changes to both. Locating those related changes together in the same commit and/or PR makes a lot of sense to me: the changes depend on each other, and thus should be reviewed together. What's the advantage of splitting them up?
- tigershark 8y agoBecause obviously the changes that you make in the gui are completely isolated from the changes you make on the server. When you are working on the gui the server code is just noise and vice versa. And it gets even worse when you use two different languages for the gui and the server.
- laumars 8y agoThat only really matters if your backend developers are a different team to your frontend developers where they'd want to be working concurrently. And even then, they could work in different branches and both teams merge into a development branch when finished. The idealistic discussions for or against monorepos often overlook the most important detail: who's working on the code and how would you want them to version control it? If it's separate projects with their own versioning then it makes sense to have them as separate repositories. If it's a single project but with individual components you'd want to version (eg because it's developed by different teams with different release timelines) then there you also have a situation where you'd want to version the code separately so once again there is a strong argument for separate repositories. However if it's one product with a single release schedule then splitting up the frontend from the backend can often be a completely unnecessary step if you're doing it purely for arbitrary reasons such as the languages being different. (I mean Git certainly doesn't care about that. A project might have Bash scripts, systemd service files, Python bootstrapping, code for an AOT compiled language (eg Rust, Go, C++, etc), YAML for Concourse, etc. They're all just text files required for testing and compiling so you wouldn't split all of those into dozens of separate repos).
- 8y ago
- fnord123 8y ago>It makes absolutely sense to have a repository for the gui and one for the server. Not really. You can have a single repo with top level directories tigershark-gui and tigershark-server.
- tigershark 8y agoWhat is the point instead of having them in two separate repos?
- lkschubert8 8y agoAny full stack change will be represented by one PR that changes from pre change to post change. Two repos would introduce a new possible state where one has the change applied and the other doesn't.
- rimliu 8y agoAnd later you add the iOS and Android clients too. Will those go into the same repo? Better to keep server and clients apart, especially if release schedules are different.
- fnord123 8y agoSure if the release schedules are different then have them in separate repos so things like tagging makes sense. But often people work with a single release schedule. There's just so many variables that go into these decisions that the thread here is bonkers. Smart people can work through problems to get the job done. Monorepo vs polyrepo won't stop people from moving forward.
- avar 8y agoIt'll be really typical for a gui/server to want to share some is_valid_payload() function. The client to validate it before sending, and for the server to do its own validation. If it's a monorepo your PR might be a 2 line patch to that function, then adding the GUI and server code. If you split it you'll first need to have a PR on the "validation-lib" repo, then once that gets in a PR on the "server" repo, bumping the "validation-lib" version dependency, and finally a PR on the "gui" repo bumping the dependency for both "validation-lib" and "server" (for testing etc.). That's before you need do deal with the circular dependency that "server" also wants "gui" for its own "I changed my server code, does the GUI work?" testing. Better just to have them in a monorepo if they're logically the same code and want to share various components.
- tigershark 8y agoThese are two separate functions why would you ever want a function that checks both gui and server? The gui validation logic belongs to the gui layer, the server validation logic to the server layer. If you have a function that contains logic from both layers there is something seriously wrong with your design.
- avar 8y agoImagine something like "curl" where a client needs to validate a manually provided request before making it. In any case, if you're nitpicking that example you're missing the point. The same would go for any number of other shared code you could imagine between a client/server trying that logically make up one program talking over a network.
- tigershark 8y agoI still can’t see how you would have a shared library for a C# gui and a Java server for example. Your communication layer would obviously live in both repositories. Even in case you are using the same language and you do have shared libraries then what is the problem? The shared libraries would surely be shared with other projects so it makes sense to have them in a separate repository.
- lucideer 8y agoMy rule of thumb is: if you need to do PRs in several repositories to do one feature, your projects are either tightly coupled enough that they should be one monolithic piece of software, or your tight coupling is a problem you should work on resolving. Requiring multiple PRs to multiple repos to roll out one user-facing feature is fine, as long as your independent modules/projects are not actually interdependent (i.e. one of those PRs will not break another independent repo that lacks a corresponding PR).
- therealdrag0 8y agoSometimes a feature needs to change a shared dependency library. But in that case you could consider the change to the dependency a single release. And ingesting it into another app a separate release.
- majewsky 8y agoJust because things change in tandem, that does not mean that they're all the same thing. When I add a new function to my backend service, all frontends that consume its API also need to be adjusted. But that doesn't mean that the backend service, its command-line clients and its web GUI client should live in the same repo.
- cc81 8y agoI really think it should if possible. Makes life much easier in my experience.
- sangnoir 8y agoIt's probably a matter of taste - but I think they should be in the same repo. I like tying test failures/regressions to a specific commit for documentation and admin purposes. Having a test fail or regression due to an 'unrelated' commit in another repo sounds like a nightmare waiting to happen when you try investigating. I the difference of opinion is between developers who work on self-hosted "evergreen" products where the latest version is deployed, and others who work with multiple release branches with fixes/features constantly being cherry-picked.
- bjourne 8y agoWhy? You are just creating more work for yourself by keeping the components in different repos. Now you need to create N commits when updating something. If your future self wants to investigate how the software has evolved there are N times as many commits to analyze.
- bpicolo 8y agoAt a past job, I had to edit roughly 5 different repositories in order to do some trivial programming task (send an email or some such). It was quite easily the least productive / most demoralizing workflow I've ever experienced. Context switching really sucks. You should aim to reasonably avoid it
- joevandyk 8y agoSending an email can have a few different responsibilities: Who is the email being sent to? What is the content of the email? What data does the email content and recipient depend on? What are you tracking on the email? How is the email visually formatted? All those things might be in different apps as the logic gets more complicated.
- kanu666 8y agoDon't mix up downsides of multirepo and bad composition of your microservices
- naniwaduni 8y ago> As a final observation, you can split big repositories into smaller ones quite easily (in Git anyway) but sticking small repositories together into a bigger one is a lot harder. So start out with a monorepo and only split smaller repositories out when it's clear that it really makes sense. If you only need to do this once, subtree will do the job, even retaining all your history if you want. I'm not sure what the easier way to split big repos is.
- clhodapp 8y agoTo split, you can duplicate the repo and pull trees out of each dupe in normal commits.
- btschaegg 8y agoIn principle: Yes. In practice, I can tell you from first-hand experience that this isn't all that simple in bigger, organically grown cases (you'll have many other things to consider if you want to keep the history in a useful way). Especially the broken branching model of SVN and co. is a problem here: In the wild, it immediately leads to "copy&paste branching" (usually through multiple commits. Migrating that to Git or Hg and splitting it up can be a challenge.
- deleted 8y ago[deleted]
- paulryanrogers 8y agoAfter trying to get the best of both with Subversion Externals and Git Submodules, I'd have to agree. At least until things are so loosely coupled they're begging for a public release. That said, some packaging solutions can bridge the gap reasonably well. Unless you need instantaneous, atomic releases.
- lostmsu 8y agoI switched to using submodules about a year ago, and they work very well for a project + a set of 4 dependencies. I handle that zoo from VS Code + Git Lens plugin. Funnily, I only use Code to handle commits to submodules, because Git Lens is not available for the full VS IDE.
- outsomnia 8y agohttps://git-scm.com/book/en/v2/Git-Tools-Submodules https://git-scm.com/book/en/v2/Git-Tools-Submodules
- bad_user 8y agoComponents might need to be released “together”, but if they are worked on by different teams, it means they’ll have a different release process, as in different timeline, different priorities. First of all this is normal, because otherwise the development doesn’t scale. In such a case the monorepo starts to suck. And that’s the problem with your philosophy ... it matters less how the components connect, it matters more who is working on it. Truth of the matter is that the monorepo encourages shortcuts. You’d think that the monorepo saves you from incompatibilities, but it does so at the expense of tight coupling. In my experience people miss the forest from the trees here. If breaking compatibility between components is the problem, one obvious solution is to no longer break compatibility. And another issue is one of responsibility. Having different teams working on different components in different repos will lead to an interesting effect ... nobody wants to own more than they have to, so teams will defend their components against unneeded complexity. And no, you cannot split a monorepo into a polyrepo easily. Been there, done that. The reason is that working in a monorepo versus multiple repos influences the architecture quite a lot and the monorepo leads to very unclear boundaries.
- forkerenok 8y agoAnd no, you cannot split a monorepo into a polyrepo easily. Been there, done that. _The reason is that working in a monorepo versus multiple repos influences the architecture quite a lot and the monorepo leads to very unclear boundaries. I think you are conflating a monorepo (where boundaries can still be established, e.g. via a module isolation mechanism specific to the stack used) with a "monoproject"/"monomodule", where is no modularization at all. Edit: expanded wording
- bad_user 8y agoNo, there's no such confusion. > where boundaries can still be established, e.g. via a module isolation mechanism specific to the stack used Unfortunately this isn't a technical issue and that's the problem.
- gitgud 8y agoIf the projects within the monorepo are decoupled and have clear boundaries then why not have them in separate repositories?... In my opinion monorepos make refactoring dependant projects much easier. However it is much harder to establish and enforce clear boundaries...
- bryanrasmussen 8y agoI can think of situations where components 'need' to release together because of organizational rules and not any actual binding between the components, in that case of course they do not need to be in the same repository. I agree that you should always start with one repo and split as needed, it's the MVR way (minimum viable repository)
- StreamBright 8y agoSo why is that? Why do we ned to couple together the software development efforts with release? Based on my experience there is no difference between the monorepo vs multirepo approach from the deployment point of view.
- andy_ppp 8y agoWhat are you talking about! In my perfect micro services world I just have these enforced bounded contexts that are so perfectly designed they never need to change. Consequently all parts of the system are perfectly independent snowflakes that can be deployed without thinking about any other parts of the system. It’s beautiful really when you think about the mess that things were before we could do this!
- scarface74 8y agoWhile I know you are being sarcastic, I really have heard bushy tailed young “architects” say something similar who just read about Domain Driven Design and then decided they were trying to “educate us”.
- andy_ppp 8y agoOh I worked on a project like this, which still hasn’t launched any software yet 5 months after I left...
- sitkack 8y agoI generate Coq proofs of Swagger descriptions that were compiled from a speech to text dump during a 10 person Hangout. Downside is that some of the protobufs aren't laid out as cleanly as one would like.
- hvidgaard 8y agoI haven't tried in Git, but with Mercurial merging repos is as simple as pulling from an unrelated repository and merging, that's it. It's a lot simpler than splitting a repo up unless you accept that all of the old history can remain, then you just make a clone and delete what should no longer be a part of the repository. But monorepo leads to tight coupling, and that is just as much a pain to work on as versioning, or two teams are simultaneously working on the same shared code, and you have not only merge conflicts, but conflicting functionality.