Search code examples
gitgit-revert

Reverting part of an earlier commit


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?


Solution

  • 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.