3

Suppose the following scenario:

  1. A new design for a specific page is required.
  2. I create a new branch for that design.
  3. I implement the design, and merge back into the master branch.
  4. Time goes by and new features is added, and so on...
  5. Management wants to revert that page to the old design -_-

As per my understanding of Git. The old feature is now history. I cannot revert the whole project to the commit where the old feature was there.

How can I restore the old feature? Can I branch from an old commit, then merge only specific files? How to do that using Git, instead of considering the old design a new one?

Edit: Ah, I messed up my phrasing here on "old feature is now history. I cannot revert the whole project...". Of course I can revert (that's the point of a SCM anyway); I meant I cannot do this business-wise; as the new features would be lost.

0

The old feature is now history

The whole point of git is to track the history of the project. What's the point if you can't take advantage of it? git only opposes altering the history.

There are multiple ways of achieving your goal:

  • git reset --hard : erases all commits from new to a specified commit. It's bad, since it conflicts with the git view of "never rewrite history". Also, doing this on a public branch would require that everybody who works on that branch to clone the repo again. Not really recommended on a master branch.
  • git revert : My favorite for this kind of stuff. It basically creates a "revert commit" - a commit which undoes the work done in a previous commit (not necessarily the last commit). For your task, you can simply revert the merge commit (although things are not that simple in practice, since conflicts might happen).
  • git cherrypick : not really useful since you merged to master, but good to know. It allows you to pick which commits to merge (so you don't merge the whole branch).
  • replace the master branch altogether by creating another branch from the desired commit, delete the old master, make the new branch be the new "master branch".
  • git revert sounds promising. you can simply revert the merge commit , so, it would only revert/undo the changes in that particular commit, but maintains changes done in NEXT commits? That would be the answer to my question. I'm aware of the consequences of that way of restoration, so never mind the mess that would happen. – Ahmed Khalaf Mar 1 '17 at 11:58
  • Yes. Basically, git stores for each commit the additions and the deletions done by that commit, and doing a revert simply delets what has been added and removes what is deleted. What you added afterwards is untouched. – Paul92 Mar 1 '17 at 12:01
6

As per my understanding of Git. The old feature is now history. I cannot revert the whole project to the commit where the old feature was there.

Of course you can. Use git checkout <commit> to travel back in time to an earlier state of the repository. You can then create a new branch which originates from that commit.

But I would recommend to try something different. Use git revert <commit> where <commit> is the commit-id which merged the new design into the main branch.

This will create a new commit on top of the current HEAD which just reverts the changes introduced with that one commit but leaves all other changes intact (as far as Git can do that on its own. Any cases which are ambiguous will be marked as conflicts). As with the normal Git workflow, you might want to do this on a new branch. After such a long time there will likely be plenty of conflicts. Not just of the syntactical kind Git notices by itself but also some of the logical kind you only see when you test the code (like the old design not working well with the new features you added over the past months). You will likely need a couple more commits until all these issues are fixed and the changes are ready to be merged into the master-branch.

0

You can check out a sepecific file as it was at a specific commit if reverting is not an option:

git checkout <commit> -- <file path>

The contents of the file will be updated to what they were at the given commit, and (IIRC) the file will be staged. You can then diff it against HEAD and manually restore the new features. This can be tedious, though less so if the design and features are nicely separated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.