Introduction

If you use Git you might be familiar with a fairly common workflow that includes checking out a feature branch from the productive branch, opening a pull request and merging the pull request to the productive branch when the feature is ready.  

However, this post is not about development workflows, it is about a problem that might come up sometimes if you work with pull requests.  
Let’s image the following development story with Nick the customer, Rachel the develope, a website with 3 blue buttons and a feature that needs to undone and reapplied later.

 

The story 

1) Nick assigns a new task to Rachel: Please change button A und button B from blue to red. 
2) Rachel checks out a new feature branch from the productive branch.
git checkout master && git checkout -b feature-blue-to-red

3) Rachel changes button A and button B from blue to red in her feature branch and commits the change to her feature branch. Then, she merges her feature branch to the production branch. 

git checkout master && git merge feature-blue-to-red && git push

4) The new feature is live. Both buttons are red, all good. Rachel gets a call from Nick. He is pleased by the new coloring but he needs to get the blue buttons back for now. Nick asks her to undo the change and postpone the release. Rachel decides to revert the pull request. All good, the buttons are blue again.

git checkout master && git revert COMMIT_ID_OF_BRANCH_MERGE && git push // COMMIT_ID FROM STEP 3

5) After a while Nick orders to release the red coloring now. Rachel is happy she still got her feature branch and reapplies the merge from step 3. 

git checkout master && git merge feature-blue-to-red && git push
What happens? One might expect to see red buttons. Instead the only one who might see red is Nick.
Nothing has changed, all the buttons are still blue.
Rachel double checks the code: the feature branch does contain the red coloring code but nothing happens to the production branch after the merge. Is Git broken?
 

Revert branch merge reverts 

No, Git is not broken. To successfully reapply the changes, Rachel would finally revert her branch merge revert. Now all the buttons are red.
git revert COMMIT_ID_OF_BRANCH_MERGE_REVERT // COMMIT_ID FROM STEP 4

 

Explanation

If you image a „revert" as „undo“, it is important to know that reverts simply undo data but not history. In the Git history the branch merge from step 3 is still there after step 4: Just the data changes were undone in step 4. Therefore in step 5 Git does not do anything because the merge already happened. 
There are ways to undo the history in Git (force push for example) but this is dangerous. 
For more details and an explanation by Linus Torvalds, the creator of Git, please read
 

Consider the danger

There was a surprise when Rachel did not see the red colors in the production branch after step 5. However, nothing got broken. 

Imagine Nick asked to finally change all buttons to red before reapplying the relase in step 5. Rachel would change button C on her feature branch between step 4 and 5.

This would have turned the production branch into rubbish because only button C would have been red, leaving the other two buttons blue. In a realistic scenario it is very likely the code in the production branch crashes badly. 
 
 

written by Roman Hatz, SRF Online, 2017/01