Reputation: 73
I have a file with following history of commits:
$git log --oneline
49740e5 3: Third version
796a330 2: Second version
539aa76 1: First version
647d060 file C creation
In each version I just added a text string to my file. I though that if I revert "796a330 2: Second version" git will generate a revert commit automatically and I will get something like this:
3: Third version
1: First version
file C creation
BUT actually this action was not automatic and I had a merge conflict to solve. Why?
Upvotes: 0
Views: 997
Reputation: 30156
Technically speaking, it uses the same machine that is used for merging, except that instead of using a late "common" ancestor
as the base for merging 2 branches, it uses the revision you ask to revert as the base for the merge and the parent of that revision as if it were the other branch
. Message is a template talking about what is being reverted..... and then, of course, conflicts have a different "meaning" from a merge.
http://ezconflict.com/en/conflictsse12.html#x53-890001.7
Full disclosure: my material (no monetization, no cookies, no tracking)
Upvotes: 1
Reputation: 30858
With git revert 796a330
, 796a330 2
won't disappear from the log. Instead, another commit is created, which tries to apply the reversed patch of 796a330 2
onto 49740e5 3
.
As to the conflicts, here's an example. Suppose that in 539a76 1
C
is empty. Then in 796a330 2
, a line hello\n
is added. And then in 49740e5 3
, the line is replaced with world\n
.
The patch of 796a330 2
is from nothing to hello\n
and the patch of 49740e5 3
is from hello\n
to world\n
. The reversed patch of 796a330 2
is from hello\n
to nothing. When the reversed patch is to be applied onto 49740e5 3
, it can't find hello\n
in C
as C
only has world\n
. So it reports the conflicts.
In other words, the changes of 49740e5 3
are dependent on 796a330 2
's changes. If you want to revert 796a330 2
's changes without conflicts, you need to revert 49740e5 3
first. If the two sets of changes are independent, git revert 796a330
won't cause conflicts in this case.
Conflicts are not errors. You can just solve them by preserving the codes you want and removing the codes you don't. The conflicting marks should always be removed.
Upvotes: 1
Reputation: 520898
The git revert
command actually is implemented by adding a new commit to the HEAD of your branch which functionally undoes whatever the commit you mention to it. So, your history after calling git revert
would actually look like this:
$ git log --oneline
abcdefg revert 796a330
49740e5 3: Third version
796a330 2: Second version
539aa76 1: First version
647d060 file C creation
Now your branch should behave as if the 796a330
commit were never made at all. One reason for using this approach to reverting a commit is that it avoids rewriting your history. Note that you could also literally remove/excise the 796a330
commit using something like an interactive rebase. But, this would reuqire force pushing your branch, which in turn could cause problems for anyone else who has checked out and is using a version of the branch with the older history.
Upvotes: 0