So I had an interesting issue come up yesterday that stemmed from a situation a couple of weeks ago. Working on a services architecture and being on the front end team, which specializes in React, you sometimes run into some hairy situations. Basically there was a combined effort to produce this certain feature, and at the very last second, the product owner decided to pull it from the release because of a bug in the back end code. Naturally the solution became, "If the UI is not there, the customer cannot use the feature." With this idea we went forward and I submitted a PR that reverted the commit where I had done the UI work for said feature.
Now let's fast forward a week or two, and product decides we need to ship this feature immediately since the bug is fixed. This is great news. I get to have my code deployed! Let's discover a few paths I went down to try to get my reverted changes back and issues that I can into.
For the sake of good story telling, let's assume a few things:
- All of my work was squashed into a single commit.
- I kept all of my work saved on a local and remote branch.
- I did not run into any conflicts in this case since it was a new feature on a piece of the application that nobody else was working on.
- Sometimes really dumb things happen in large teams when code is getting smushed together to be deployed.
Hey Dummy! Just Revert the Revert and You're Good!
At the very top of my list was just to revert the revert commit. Spoiler Alert! This did not work for me and was a crazy goose chase. Here's why.
The first step to this solution is finding the SHA for the revert commit. For some reason I could not find it in the Git log. It was simply in the comments for the tagged branch that was deployed. What I quickly ended up realizing is that the revert commit had been squashed into some other changes before the release, and that made for a sticky situation where I could not just "revert the revert that reverted my changes"
Hey Dummy! Just Rebase and You're Good!
git fetch git rebase origin/develop
The second thing I tried to do was a simple rebase of my old feature on our develop branch, but that yielded nothing useful. If I rebased, the revert obviously removes my UI portion of the feature and we still have a problem.
Hey Dummy! Just Change the Commit SHA so the Revert Can't Revert Your Changes!
After resetting my local branch to the remote branch so I could undo the rebase changes, I tried this.
git fetch git commit --amend // Write new commit message to change the SHA of my commit to trick the git revert into not reverting my changes git rebase origin/develop
This ended with the same result. The revert is smart enough to know what I am doing and if I look at everything after I rebase, my changes are gone.
Solution #1: One File at a Time
We want my changes from my feature branch to be in develop right? So one approach is to check our develop make a new feature branch and bring things over one by one.
git checkout develop git pull git checkout -b (some_new_branch_name) git checkout (branch_where feature is) -- src/.../...(path to file)
Doing this approach I will have to bring in every file one by one and hopefully not miss anything while bringing the stuff over. I was not a fan of this approach since my changes were in half a dozen to a dozen files, and I did not feel comfortable with this in case I missed one of the files. This would mean an incomplete, or even worse, broken feature being shipped to production.
I think what I ended up with was slightly more elegant and got everything in one shot.
In the end, we have a branch with some changes that we want in develop, and those changes are squashed into one commit as the Git lords intended. All I really want to do is save those changes and apply them to my develop branch.
This was my "so called" elegant solution:
git checkout sexy_feature git checkout -b backup_of_my_sexy_feature_just_in_case git reset HEAD~1 // The above will unstage and uncommit everything in the last commit. git add . // We need to stage everything since I added completely new untracked files git stash // This will put all of the staged changes into one stash git checkout develop git pull git checkout -b bringing_sexy_feature_back git stash pop // Adds the changes into your branch, but not staged. git add . git commit // and you know the rest of the story from here
From here the story is bland where I submitted a PR and went about my day after losing a bunch of time in the Git downward spiral. Hopefully this post helps out some people running into the same issue.