Code Symbiosis

Programmers write a lot of code.

Many programmers usually write even more code. 

Inevitably, people write code that conflicts with another person’s.

There are a few ways to reconcile this so that the new can be combined with the new. 

A lot has been written about the tradeoffs of merging in changes versus rebasing off of the master branch. If you’re not familiar with git merge or git rebase, then check out this guide

But why try to do all this fancy stuff if you just push your code up to Github and resolve any merge conflicts you may have? 

Because there are two kinds of conflicts: lines of code versus logical. 

A tale of two conflicts

Code may have edited lines by another person, so that’s pretty obvious it’ll be a conflict when you try to merge code. This is caught by git and its implementation on Github. 

But there can also be logical conflicts. A simple case might be you’re writing new code that utilize some helper function, but you’re not up-to-date with master and a colleague has deleted or renamed that function. This wouldn’t be caught by git (and thus Github), so if you think merging into master without conflicts means everything works, you may be wrong. 

But do tests and continuous integration help? 

They can, but those things are looking at the latest code in your branch. If your branch doesn’t have the latest changes, it won’t be able to check for any breakages in functionality. 

This is exactly why Github has a feature in protected branches (usually at least master) that let you know when you’re not up-to-date with master. By merging in the new code on master into your own feature branch, you can be more sure that things work if your pull request is approved and merged. 

Some people want to keep the git log clean with real logical commits and think merge commits from master are unsightly and unmeaningful. In this case, that’s what rebasing and squashing are for. If you want to keep the history of commits without squashing into one commit on master, rebasing is a good option, with only the loss of the timing of the commits (not their logical order and meaning). 

If measures aren’t taken to enforce branches that are up to date with master, it’s not the end of the world. Programmers just need to have more initiative to do it themselves, but this is a poor risk management strategy. The master branch is usually on the pipeline for production, so if things are breaking there, they may break for other people as they branch off of master. This cascading failure is not always going to happen, but it can be easily prevented by enforcing that pull requests are up to date with master before merging. You can cut the pipeline short by actually not deploying master unless it passes all your tests and continuous integration, but if there’s a breakage, you’ll still have a bad master branch, i.e., not good. 

How about if you work at a huge company and people are merging into master all the time? Will you be stuck rebasing or merging forever!? Thankfully, Github has a rebase and merge button that you can press for pull requests. This will automatically rebase your commits on top of master right before it’s merged into master. This helps a lot, but it’s still best to keep up to date before merging the pull request so that you can fix problems before they are in master. 

Keeping up with the master(s) 

To goal of git, merging, or rebasing is to combine code changes in a decentralized, but structured, deterministic way so that the end result is simple to understand and/or change. 

To do this, you need to keep up to date with master. You can do it by merging in the master branch’s changes into your own feature branch or by rebasing your branch on top of the latest master branch’s commits.