Read more

How to revert features for deployment, merge back, and how to stay sane

Arne Hartherz
January 13, 2012Software engineer at makandra GmbH

Removing features and merging those changes back can be painful. Here is how it worked for me.\
tl;dr Show archive.org snapshot : Before merging back: reinstate reverted features in a temporary branch, then merge that branch.

Scenario

Illustration web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
Read more Show archive.org snapshot

Consider your team has been working on several features in a branch, made many changes over time and thus several commits for each feature.\
Now your client wants you to deploy while there are still stories that were rejected previously and can't be deployed.

In this situation you basically have 3 options:

  1. Invest all time into finishing those stories
  2. Cherry-pick all commits that are good for deployment (e.g. into your master or production branch)
  3. Merge and revert those commits that introduced changes that should not happen (useful if the majority of features should go live but you don't want to pick hundreds of commits).

While it does not feel right to invest time into removing features that will be finished in the near future and you'd prefer the first option, it's sometimes just not possible and you must invest time on one of the other options.

How reverting worked for me

Option 2 sometimes is not feasible so let's say you went with number 3 and removed features. When you merge those changes back after deployment, you may run into conflicts -- especially if your team continued working on the features you've been reverting for the last 2 days.

To keep it as little annoying as possible, you should keep a few things in mind:

Reverting:

  • Branch off your team branch and create a separate branch to work on.
  • Revert each feature that should not go live by itself, don't mix reverting feature A with reverting feature B if possible.
  • Revert all commits of a feature from the most recent back to the oldest.
  • When you need to dig through lots of commits, you will eventually run into conflicts. Expect them and be fine with it. :)
  • When done, use git rebase -i to squash all reverts into one commit. This will make it a lot easier to restore functionality later.
  • In the end, you should have 1 commit for each feature, e.g. "Remove new calendar design".
  • When you encounter commits you missed, you can revert them and squash them onto a previously consolidated commit. Having as little commits as possible to restore later is key.
  • Run tests and fix them, if necessary. Maybe tests were added that expect the removed functionality as a side-effect.
  • Merge the master into your branch regularly, especially when you have multiple teams preparing for deployment and adding their changes there.

Deployment:

  • Before merging your reduced feature branch into master or production, check some spots manually on your machine.
  • Deploy to a staging machine and have your client check the application. Since your client requested it, they should also take the blame of checking it. You probably did it correctly anyways, but especially when removing larger features it's important to have a "second opinion" on the application's state.
  • Once all is cream green, deploy away.

Merging back:

As said before, your team probably continued working on the features you removed in a separate branch. Merging back may be ugly but this is where your few commits come in handy.

You have 2 options to get the deployed state into your team branch and previous features back:

  1. Merge back master into your team's branch, then revert your "Remove XY" commits.
    : This may seem fast but can introduce more conflicts than necessary. If there are lots of conflicting files, try the next approach:

  2. Branch off, e.g. into master-with-reinstated-features, revert your "remove" commits there, then merge that branch into your team branch.
    : This can still give you some conflicts but they were significantly smaller for me on the project I did this on. Basically it's not much slower than the above but can save you lots of trouble.

Resolving conflicts can be tricky. If the diff is too unreadable, you can cheat by doing a git show master:path/to/file and see what the deployed state looks like -- it's probably correct. If your team branch holds more code, it may just be unnecessary or even redundant.


In general, this is rarely fun. If you are asked to do it, try to convince your client of the first option since investing time into removing almost-finished features gives them no real value for their money. Still, if they want it, I hope this guide helps you keep your sanity.

Posted by Arne Hartherz to makandra dev (2012-01-13 13:49)