Git Gud!

I am no git wizard, not even adept really. I know just enough to “git” by. ;) Let me regale you with a tale of my git shenanigans and you can help me “git gud”.

The title of this post is really an admonition for myself more than anything else. As someone who has worked as a “professional” programmer for a whopping 5 months, git is still, largely: ¯\_(ツ)_/¯ Sorcery?

Those of you reading this may hear my problem and think, “You dolt, if only you had done <enter simple solution here: snark optional>” and if that is you, I cannot stress this enough, please let me know what that solution was. In the mean time, let me paint you a picture of my problem and the steps I took to solve it.

The Scenario

I was working on making some large improvements to a website that multiple people here have there hands in as well. So like I’m supposed to, I branch off develop and start making my changes, we’ll call this branch feature. While in process, I discovered that a couple pages I was working on, as well as a couple I wasn’t working on, were all vulnerable to some XSS attacks through user input markdown.

Since fixing this was adjacent to what I was actually working on, and affected more than just where I was making changes, I decided to fix it separate from my current branch. So again, I branched off develop (this branch we’ll call xss), made my fixes, and merged these changes back in to develop. Now I needed this fix in my current branch, so I pulled develop into my feature branch and continued working.

A couple days later, I took a break from working on feature and spent a little time working on some UI updates on multiple pages. So again, I made a new branch from develop, let’s call it ui, and I started making my changes there. Once they were complete, we squashed and merged them into develop. As before, I wanted some of these UI changes on my feature branch, so I pulled develop into feature once more. And here is where things got weird.

The Weird

First, I noticed as soon as I pulled develop into feature, almost all the changes I had made to feature were reset to the state the files looked on develop. Mind you, neither ui nor xss had made any changes to these files so there shouldn’t have been anything in the changelog that created conflicts. I wasn’t even warned of conflicts. I simply ran git pull origin develop on feature and feature was almost completely reset to its original state.

Now I thought, this is weird. So I reset feature back to right before I had merged in develop and used git’s cherry pick feature instead to only grab the specific commits off of develop that had the correctly changed files. But now feature’s changelog included these commits I picked off develop, so when I created a pull request for feature into develop, all the changes I had cherry picked from develop showed up in the PR as new changes, muddying the water of what changes feature was actually making, and making code review that much more difficult.

The Solution

This was the solution I landed on, whether or not this is the right one, I’m not sure. First, we figured the problems must have arisen from the fact that when we merged ui into develop we did a squash and merge, not just a straight merge. Mostly this guess comes from the fact that when I merged xss into develop and then develop into feature, I didn’t notice any loss of progress on feature, but after squashing ui, now develop was making weird changes to feature. If squashing wasn’t actually the cause, I would love to hear what was. But the solution that ultimately succeeded: git rebase. Here is my understanding of why that fixed it.

The Problem:
  to here <--- this was reset
  |            |
  v            v
  /-----/------/  feature
 /     /      /<--where things got weird
|-----/------/    develop
 \---/\     /     xss
       \---/      ui

How rebasing changed things:
              /------------ feature
|-----/------/  develop
 \---/\     /   xss
       \---/    ui

Rebasing feature on to the new state of develop (in my understanding) shifted the branch off point forward. This way, instead of having to merge various states of develop back into feature (where changelogs seemed… funky?), as far as git is concerned, feature has only ever been built on develop after all those updates to develop were created. This worked, I got all the fixes from develop without resetting anything on feature. Huzzah! I live to code another day.

Hopefully this won’t have far reaching consequences on branches or PRs in the future. I can’t foresee how it would, but then, up until a week ago, I couldn’t foresee how trying to merge changes from my base branch into my feature branch could break things either. So I really don’t know what I don’t know. If this somewhat convoluted tail of my failures was helpful or interesting to you, let us know! And more importantly, if you can foresee doom in my future due to my chosen solution, or if you know of a better one please let us know. I’d love to learn more about this tool I use everyday and barely understand. I’d love to git gud!

Jimmy Keith wrote this on 9 April 2019