A Dummy's Guide to Reverting the Revert that could not be Reverted
Tags: github, githunt, refactorit, javascript
Published: 2019-06-06 20:17:16

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:
1. All of my work was squashed into a single commit.
2. I kept all of my work saved on a local and remote branch.
3. 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.
4. 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.