首页 > 解决方案 > git revert issue with merge strategy (theirs)

问题描述

I want to revert to a previous commit of the branch with taking all the changes in that commit and nothing from the current one.

I have setup my test directory as below:

mkdir test_dir
cd test_dir

git init .

touch a_file

git add a_file
git commit -am "file added."
# say commit id 0_afile

echo "1 line" >> a_file
git commit -am "1 line"
# say commit id 1_afile

echo "2 line" >> a_file
git commit -am "2 line"
# say commit id 2_afile

echo "3 line" >> a_file
git commit -am "3 line"
# say commit id 3_afile

echo "4 line" >> a_file
git commit -am "4 line"
# say commit id 4_afile

When I run git revert --no-edit -X theirs 2_afile. I'm expecting content of 0_afile, 1_afile and 2_afile commits but the result doesn't contains content of 2_afile. Could someone points out what I'm doing wrong.

标签: gitgit-mergegit-revert

解决方案


This seems somewhat self-contradictory to me:

I want to revert to a previous commit of the branch ...

(boldface is mine; note that this is easy; see, e.g., Reset or revert a specific file to a specific revision using Git? though it's for some specific file or files)

... with taking all the changes in that commit and nothing from the current one.

Commits aren't changes, commits are states.

To use a simple example, suppose I tell you that it is currently 68˚F (20˚C) outside, on a Friday. That's a state. If I ask you what the change is from yesterday's temperature, can you tell me? What else do you need to know first?

If the temperature goes up 9˚F (5˚C), that's a change. If I tell you it went up that much on Monday vs Sunday, what temperature was it on Sunday? What else do I need to tell you first?


In Git, each commit is a complete snapshot of all the files, in whatever state they have at the time you make the commit. To get changes from a commit, it's necessary to compare that commit to some other commit. The obvious "other" commit is the immediately-preceding commit, i.e., the commit's parent. If a commit has only one parent, Git can do this automatically: it extracts the previous commit's files (a state), and the given commit's files (another state), and then subtracts them to produce the set of changes.

If you want the content of one file from a previous commit, that's easy; see the linked question, and this is a duplicate. What git revert does is quite different: it turns a commit—a state—into a change, and then tries to apply that same change to the current state. See my recent answer to Revert only a single file of a pushed commit, for instance.


推荐阅读