Search code examples
gitgithubversion-controlgit-revert

What exactly git revert does?


I am trying to figure out what's the difference among git reset , git revert and git checkout. There is something I can't understand about git revert.

I made a simple app and touch 2 file: file1.html.erb and file2.html.erb, then I subsequently created 4 commits:

commit #1: add some code in the first line of file1.html.erb
commit #2: add some code in the second line of file1.html.erb
commit #3: add some code in the third line of file1.html.erb
commit #4: add some code in the fourth line of file1.html.erb and file2.html.erb

Basing on the case above:


git checkout

if I executing git checkout HEAD~2, the local file would back to the state of commit #1, nothing would be changed if I checkout to previous HEAD.


git resert --hard

git reset HEAD~2 --hard This would alter the commit history and local file, totally back to the state of commit #1. While --mixed would change the commit history and staged snapshot, --soft would only change the commit history.


git revert

When I executing git revert HEAD~2 , the terminal returned this:

caven@CavendeMacBook-Pro ⮀ ~/demo/demo ⮀ ⭠ branch01 ⮀ git revert HEAD~2 error: could not revert ed3279f... commit 2 hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' hint: and commit the result with 'git commit' ✘ caven@CavendeMacBook-Pro ⮀ ~/demo/demo ⮀ ⭠ branch01± ⮀

And in file1.html.erb , git labeled the code as:

I add this line at first commit.
<<<<<<< HEAD
I add this line at second commit.
I add this line at third commit.
Simultaneously, I add this line and some code in file2 at fourth commit.
=======
>>>>>>>    parent of ed3279f... commit 2

But in file2.html.erb, nothing changed, the code which I added at the fourth commit still there and git didn't label any conflict.

This confused me, git docs says "Given one or more existing commits, revert the changes that the related patches introduce, and record some new commits that record them."


I have 3 questions:

  1. In this case, what exactly git revert is doing? Does it just compare the difference between current state and specified commit's state, then labels the conflicts?
  2. I didn't specified any file, why git only labeled conflicts in file1, what about file2? How will git handle it?
  3. What should I do next step? Should I delete the confilct code and create a new commit? Or should I do anything else?

Thanks a lot !


Solution

  • Revert is trying to remove the changes performed on revision HEAD~2, and like applying any patch, it can generate a conflict. The only revision that will be reverted with a guaranteed result of no conflict will be HEAD (if it's not a merge commit), but other revisions might generate a conflict (if they mess up with code that was touched on revisions after the one you want to revert. If the code involved hasn't been touched since, then it will probably be reverted cleanly ). When the revert is finished, a new revision will be created (which is different from both checkout and reset).