Back to Writing

Rebase, squash, merge.

Published:

Preamble

Recently while working on a project with a team of 5 engineers, one engineer asked me why it was, that when working on a local feature branch, then when we rebase on main, that they get x commits ahead of their remote feature branch, but y commits behind remote. I knew in my mind, that there was a disconnect between the branches - but the point of frustration was that we had to “force-push”, potentially destroying history on the remote feature branch if others had merged on it.

Preferred way of working with Git in a team

Typically, at time of writing this, my preferred way of working in a team of greater than 2 engineers goes as follows:

Gotchas

While the above method of rebase, squash & merge works quite well, there is the problem of the force push.

When you rebase on main, your local and remote feature branch are out of sync. This leads to having to “force push” to your remote feature branch. This can make new and seasoned engineers nervous, and rightly so. If during the rebase, the engineer has “got something wrong”, then the force push occurs, they will have wiped any backup record of their work.

Before the rebase, and force push occur, it’s best the engineer does a manual “face-check” of the code to make sure that the force push will not overwrite any code expectantly. Code may exist from other engineers committing and pushing to the feature branch, or even if your team uses the suggested changes feature of github. This can become especially problematic when one engineer rebases and the other doesn’t. This highlights how when working on a history, were rebasing is used, communication must align between participating engineers. Ensuring that they have a copy of those commits on their local copy of that history. This is mostly avoided if teams stick to branching, and that there is an obvious “owner” of the branch who is in charge of managing the state of that branch. At most you would only have 2 engineers working on a branch at a time, in the scenario that they are pairing. If you are forming a mob, you typically have one “driving” engineer who still acts as the owner. If you find that you’re clashing a lot in this manner, you may need to encourage engineers to branch off of feature branches when they find their work is extending beyond a minor fix. After all, the team is familiar and in the habit of not working on main, so when you’re working off someone else’s feature branch, it should be treated as another engineer’s “main”, a place you wouldn’t commit directly to.

Visualisations

There are some great visualisations on the git-scm website about rebasing vs. merging.

Github has some great material overall about resolving merge conflicts.

And I put together an excalidraw, that explains how rebase, squash merge plays out over time.