1.2 Git Basics: Distributed Workflows
In this lesson, I’ll explain how Git works as a distributed system, with separate repos of roughly equal power. Not every developer has the same permissions, though: write access may be given only to trusted or senior developers, who will be responsible for reviewing and merging commits. I’ll show you a couple of the most important distributed Git workflows—integration manager and benevolent dictator—and I’ll explain how code changes are reviewed and merged in each one.
1.2 Git Basics: Distributed Workflows
Git is pretty awesome when it comes to sharing code. I think it's fair to say that next to simple and inexpensive branching, the convenience of distributing code with Git made it the powerhouse it is today. Git allows us to have multiple repos, unlike centralized systems, every repo is a node of equal power. Their permissions can differ though, read and write access can be distributed as needed. Being able to easily contribute code offline is another cool aspect we take for granted. There is more than one distributed workflow. The flexibility to adapt workflows to the preferences of teams or to the size of projects is quite impressive. Daunting for beginners maybe, but also very enabling once you face production environments or bigger open source projects, for example. Git's power comes from being decentralized, making every copy of the code equally important. That means that every contributor is potentially a node and hub at the same time. Usually we deal with canonical repos, which are like the official versions the other repos are striving into. The main repo often has one or multiple maintainers to check the quality of the code that people contribute. Developers clone or fork from these master repos, work on new commits, and push these back into the so-called blessed repo. I think it's best to see these changes as code suggestions to the canonical repo. Through a pull request, we can discuss if these suggestions are appropriate or if they need to be approved or even declined. We should discuss two major variations that are important for understanding most model workflows we encounter these days. The integration manager workflow and the benevolent dictator model. Both are variations of a multi-repo workflow. The blessed repo, in this scenario, has one or multiple integration managers who have the final say what goes into the blessed repo. It is public in the sense that contributors can clone or fork from that version. They have read access. For pushing new code into that main repo, they have to go through an integration manager, though. They check the code from other developers that is suggested via the publicized branches. If they find the new code acceptable, they check out the new branch, test it, and merge it into their own copy first. As the final step, the integration manager pushes the new code into the blessed copy. That way the blessed repo only gets new code after it has been tested and checked by the integration manager. This workflow will become very familiar to you when you start working with the tool like GitHub. This service lets you fork copies from a main repo and lets project mainainers integrate these changes through these published copies of your code. Everybody can work asynchronously and nobody needs a way to continue their work. The benevolent dictator workflow is a variation of the system above. It has a few more players involved and is maybe better suited for bigger projects. By big, I actually mean huge. Stuff like the Linux kernel with hundreds of developers involved. I thought it is educational and interesting to know how this works, even if you're not yet ready to contribute under such circumstances. This approach needs multiple integration managers, so-called lieutenants. This system has one major integration manager at the top, the benevolent dictator. He's responsible for the final call, what goes into the blessed repo. This repo is again, the reference repo everybody has to pull from. The master branch developers base their work on is from the dictator. The lieutenants are responsible of pre-selecting code contributions. They often have specializations. On big projects, this would be too big of a burden for a single individual. When developers are finished with a feature, they push their branch to remote that is inspected by one of the lieutenants. If the code suggestions are acceptable, lieutenants will merge these new commits into their own master branch. Then when the benevolent dictator has time to look at the changes the lieutenants deem appropriate, the final check takes place. If the new additions are okay, the dictator merges them into his repo. After that, other developers and the lieutenants can pull down these changes and rebase their work on top of the updated master branch. In this picture, you can see the flow how all these repos work together. Although this workflow is not all that common, it clearly demonstrates what flexibility Git offers to delegate work and collect new contributions through multiple integration points. This approach scales exceptionally well.