Erben Mo
Erben Mo

Reputation: 3634

How can I revert a git commit but preserve the very original git commit history (in git blame)

I am going to revert a problematic commit but after the revert if I run the git blame on the file I am seeing my revert as the most recent commit that touched those lines. That makes sense but not very useful since I want to see the git history of the original file. (i.e. just like the problematic commit and the revert never happened).

Is there a way to do that?

Thanks!

Upvotes: 3

Views: 2434

Answers (4)

Kim
Kim

Reputation: 594

If you don't want to edit your history and you don't mind an extra commit you can do this by:

  1. Go back to a commit before the changes which have been reverted.
  2. Create a branch, and merge your branch into it with the option --no-ff (no fast forward)

If you blame the new branch you should now see the original author for the lines which were reverted.


Just a note, this should in theory automatically happen if you at some point merge your branch into a master/main making this unnecessary (assuming your don't ever merge into master/main with fast forward).


I haven't tested how any of this works if you revert something from an older branch which already is merged into master/main. My best guess would be that you would need to create the branch from step 2 at a version of master which didn't have the change which should be reverted. it might just work ¯\(ツ)/¯.

Upvotes: 1

eftshift0
eftshift0

Reputation: 30297

If you want to "remove" a commit from the history of a branch then you have to: - git checkout the previous revision - git cherry-pick revisions you want to keep that are after the revision you want to remove

Say you wanted to remove branch-name~3 from the history of a branch:

git cherry-pick branch-name~4 # (this is a keeper)
git cherry-pick branch-name~3..branch-name # apply revisions after branch-name~3

Voila. It never happened in the first place. In your case, exclude the revert revision when cherry-picking and you are done.

Upvotes: 1

jthill
jthill

Reputation: 60547

Run your blame from the revert's parent, see the git blame docs; you can even specify an explicit list of commits you're interested in checking and just delete the revert from an ordinary rev-list's output.

Upvotes: 0

amalloy
amalloy

Reputation: 92117

A revert is no different from a new commit with a reversed diff. So, no, you can't make git-blame ignore the original commit or the revert (unless you are willing to change history, in which case you aren't actually reverting anything at all).

However, because it is just like any other commit, you can do just what you would with any other commit, if you see that the commit that last touched some lines was not useful, and ask git-blame to annotate a previous version of the file.

For example, suppose that you ran

$ git blame HEAD -- foo.c

and saw:

7507efdad27 foo.c (amalloy) ...

on the line you are interested in. You decide this commit isn't useful, because it was a revert. You can check which commit was reverted by that commit, with git show 7507efdad27.

Suppose that yields 673bdae7548: You can then ask for a blame view of the file before that commit:

$ git blame 673bdae7548^ -- foo.c

Which will show you the blame before the commit that was reverted, so the lines you're interested in will be annotated with the commit that last touched them before the commit that was reverted.

Upvotes: 1

Related Questions