Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: remove earlier commit but keep recent changes

Tags:

git

I got some commits in my repository:

like:

A - Added Feature A B - Removed Feature B C - Redesigned Feature C D - Added Feature D E - Added Feature D 

Where E is the most recent commit I made. Now I want to get rid of the changes I made with feature C but I want to keep the changes added with D and E.

I hope you can help me.

Thank you

like image 383
Bernd Strehl Avatar asked Jul 16 '13 10:07

Bernd Strehl


People also ask

Can I delete a git commit but keep the changes?

The easiest way to undo the last Git commit is to execute the “git reset” command with the “–soft” option that will preserve changes done to your files. You have to specify the commit to undo which is “HEAD~1” in this case. The last commit will be removed from your Git history.

How do I remove a previous commit from a branch?

You can simply remove that commit using option "d" or Removing a line that has your commit. In the latest git version there is no more option d. You need just remove lines with commits from rebase to delete them.


2 Answers

Interactive rebase is your friend!

As others have said:

$ git rebase -i HEAD~5 

...where -i is the interactive flag, and HEAD~5 means include the last 5 commits in the interactive rebase.

When you get editor up as a result of issuing the above, take a look at the comment in the opened file:

# Commands: #  p, pick = use commit #  r, reword = use commit, but edit the commit message #  e, edit = use commit, but stop for amending #  s, squash = use commit, but meld into previous commit #  f, fixup = like "squash", but discard this commit's log message #  x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out 

The key bit for you is If you remove a line here THAT COMMIT WILL BE LOST.

So, delete the lines that reference the commits you want to be rid of, save and close, and git will handle the rest (you may have to fix some conflicts depending on the nature of the commit and the revert you're trying to delete).

It's important to note that if you have already pushed your code and others have pulled it, the above will not work as the commits will find their way back in there the next time someone who has your branch checked out does a push. The interactive rebase deletes the commits to the extent that there is no record of them, so the other clones do not know they have been deleted. Next time they push, they'll try and re-instate them as the local clones "see" that the origin does not have the objects (commits) that you have deleted.

like image 62
BenLanc Avatar answered Sep 17 '22 23:09

BenLanc


If you only want to "get rid of the changes" (as specified in your question body) as opposed to actually "removing a commit" (as specified in the title), an easy option is adding a new commit, doing exactly the opposite of what the earlier commit did.

It's not foolproof and it can result in conflicts due to changes done since, but it doesn't alter history, allows you to document the reversal and its reasons, and plays well with other working copies.

git revert is the tool used to make such evil twins of a set of commits.

like image 28
aib Avatar answered Sep 17 '22 23:09

aib