Let’s have a merge party – Safe Git Merging

As an indie developer I spend a lot of my time working on my own, however as a contract developer I work in teams of many other developers. Most of the time when I’m contracted I am brought into project in a frantic state of playing the little dutch boy. As a result merges go haywire and sometimes we don’t pay enough attention and undo a fix due to a git conflict.

Here’s the workflow I use, and I try to encourage others as well, it keeps things safe.

First if you’re doing a quick fix, generally the remote branch you started from hasn’t changed. But if it’s a several day fix, you may find that your remote branch you started on has had updates. You want those, and if you’re really paying attention would have merged those as you went along.

My workflow on a team are these processes.
1) Create a version branch that you’re working on.
2) Everyone branch off that version when applying fixes / features to the next version
*3) When a fix is done, do a pull request (code review, if not using Bitbucket / gitHub)
4) When approved, merge back into the develop version, and delete the fix branch.
5) other developers should then update their working branches to make sure they pull in the changes made, as their commits will happen on later.

Here’s a crude example:

Here we are with our 3 branches
Screen Shot 2014-08-22 at 10.59.15 am

In this case you can see that everyone started from develop/1.0.0.
We then created 3 branches off that. Branch 1 bugfix_ticket_355 was committed first as it’s a step ahead. Let’s say 355 was then merged to develop

Screen Shot 2014-08-22 at 11.01.36 am

Now you can see develop is a step ahead of our other tickets. Well since those haven’t committed yet we may have some conflicts. We never want to push conflicts, so here is where my workflow kicks in.

2 Scenarios: Developer A has the feature 353 ticket. Developer B has the 345 bugfix
Developer A, knowing he just had a remote merge as he did the pull request, then updates his local branch with the changes.
DA -> Git fetch
DA -> git merge origin/develop/1.0.0

Developer B does not update, as he was in the toilet.

Now look at the repo:
Screen Shot 2014-08-22 at 11.05.08 am

Developer A is up to date, Developer B is not.

Seasons change, time passes. Developer B is ready to push.

So before pushing to the remote this is what Dev B should do:

— Safe Merge —
>git fetch origin
>git checkout -b remote_merge //branch off the bugfix working branch, in case something goes wrong your original branch is intact
>git merge origin/develop/1.0.0
>!–conflicts–! – Grab another dev to review with
>resolve conflicts >git mergetool< >git commit -m “resolved conflicts with remote”
>git checkout bugfix… branch //return to the actual working branch
>git merge remote_merge
//Safely merges as you already resolved all conflicts, now safe to push up
>git branch -D remote_merge //delete the local merge branch as it’s not needed anymore
>git push origin
–Code review, rinse repeat

This becomes second nature after a while, but I just thought I’d document it here. It may sound like gobbly goo, or too much work for something ‘simple’, but just wait till a bad merge comments out a feature that takes your app down for a couple weeks of investigations just to find out you did a bad merge.

Rules to live by:
When working on team, all conflicts resolved in tandem.
Pull requests work, do them.
Never push up a branch without testing the merge locally. Leave your remotes clean.