Home > Blockchain >  Reverting part of an earlier commit
Reverting part of an earlier commit

Time:06-04

I know I'm missing something obvious but... let's say I have 3 commits affecting the same two files: a and b. I want to revert the changes made in the 2nd commit to a, but I don't want to lose the changes made in the third commit to b. If I revert and then recommit, won't that overwrite my new changes for b in the third commit?

CodePudding user response:

When Git performs a revert, it essentially takes the patch for that commit and reverses it, then applies it to the working tree and index. It uses the same machinery as cherry-pick and some forms of rebase under the hood to do so and works very similarly.

If the changes you're making in the revert are in different parts of the file from the changes you made in commit 3, then the revert will apply cleanly, and you will have the changes from commits 1 and 3 but not 2. If the changes in your revert overlap (or nearly overlap) with the changes in commit 3, then you'll probably get a conflict, which you'll have to resolve to continue. In no case is Git going to simply undo the changes in commit 3 because you asked to revert commit 2.

This is why when you are reverting multiple commits in sequence, you want to revert the later ones before the earlier ones, because that undoes the changes in the order they were originally done, minimizing the risk of conflicts.

CodePudding user response:

tl;dr: It sounds like you intend to do a partial revert of commit 2, and if you do that, then No, file b will not be changed at all.

Details: Based on the question and the comments, we know:

  1. All 3 commits modify both files a and b.
  2. You wish to revert commit 2, but only file a in that commit, based on the comment:

If I revert commit 2 and modify a (only) and then commit the changes

It's important to realize that git revert is merely a convenience and a convention, and you could do exactly what revert does manually, if you wanted to. Regardless of whether you use the revert command or do it manually, the end result will be a new commit, (let's call it commit 4), that undoes the result of a previous commit. In your case, you want to undo a portion of commit 2, so you could manually undo the change of file a and create commit 4 manually. I assume if you did it manually you would not expect file b to be affected in any way.

You could also use the revert command to assist you with making commit 4, for example:

# revert commit 2 but don't commit it yet
git revert <commit-2-hash> --no-commit

# unstage file b so that only the change to a is reverted
git reset b

# restore file b so that it is no longer modified
git restore b

# commit the change
git commit # Adjust the commit message appropriately

If you use the revert command, Git proposes a useful commit message. However, if you modify the revert in some way, I recommend modifying the commit message like this:

Partial Revert "Previous commit message..."

This commit only reverts the changes to file a.

This reverts commit <commit-2-hash>.

Additional Note: if you do a regular revert instead of the partial revert described above, then the changes to file b in commit 2 would also be undone. See bk2204's answer for more details about how this works.

  • Related