Git恢复不能按预期工作 [英] Git revert does not work as expected
问题描述
我遇到了 git revert
命令的问题。我使用Ubuntu 12.04 Linux和Git 1.7.9.5版本。
- 我创建了一个全新的
b_test_repo
在我的本地PC上运行,并从远程origin b_test_repo
进行跟踪。 - 本地创建了一个文件在两行文本中提交
A
),并且只在本地master
分支中成功提交。 b
$ b为了试用
git revert
我生成了3个更多的提交,每个提交一行的文字。因此,我的master
提交历史记录如下所示:A - B - C - D
其中
-
A
- 包含第1行和第1行的新文件2 -
B
- 添加了一行 -
C
- 添加了一行
-
D
- 添加了一行
完成所有这些提交后,文件包含5行:
line1
line2
line3
line4
line5
然后,我想恢复提交
B
,这将呈现没有line3
的文件,该文件由提交B添加
:git status
#分支master
没有提交工作目录干净)
我输入:
git revert -n master〜2
可恢复效果提交
B
而不提交更改,但得到以下内容:
错误:无法恢复1a13ad6 ...添加一行
提示:解决冲突后,标记更正的路径
hint:with'git add&hint:并提交结果'git commit'
我很困惑为什么我会发生冲突,也就是说为什么Git会在文件中找出需要更改的问题。
我在这里想念吗?请赐教!
删除该行会导致与更新版本发生冲突,这会改变 > line。
所以如在git恢复时应该怎么做中止与错误消息?,你需要解决合并,添加和提交。
更简单的方式来恢复该提交将是一个交互式转换:
git rebase -i< SHA1 commit a>
然后您放弃提交
b
。<
但是,只有当您尚未将分支推送到 上游回购 ,因为它会重写提交历史记录。
如果您确实已经推送了,那么
git revert
是正确的方法,为了生成一个新的提交取消b
(并在上游回购中推送新的提交)。
详细信息:您的示例生成以下合并冲突:
C:\ Users \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
* 3d888c4 - b
* 8c7155f - a
(
git lg
是一个别名花哨的git log
)
如果存在冲突,我更愿意在合并或还原之前同时查看原始部分的来源(他们的),目标(我们的)和:
git config merge.conflictstyle diff3
然后恢复:
git revert -n master〜2
这会给:
line1
line2
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< HEAD
line3
line4
line5
||||||| 3d888c4 ... b
line3
=======
>>>>>>>父母的3d888c4 ... b
这样,你会看到
git revert
does:合并之间:
- 提交的父
b
(它显然不包含b
修改)
- 和
HEAD
合并无法确定以开头的部分第三行:
- 该部分不存在于
a
中(===>>>>< / code>部分:'他们'一方) < b
(原始部分在||||
和====
之间,如前所述revert
,只是line3
) - ,它也是 修改于
HEAD
(<<< ||||
部分,添加line4
和line5
,即使line3
的外观不变)
如果以commit
a
开头,合并冲突更加明显:
line1
line2
line3
line4
line5
结束提交
d
为:line1
line2
line3b
line4c
line5d
(提交
b
添加'd
'到第3行,提交c
在第4行添加了'c
',提交d
添加'd $ c
然后一个回复会给你:
git config merge.conflictstyle diff3
git revert -n master〜2
cat afile.txt
line1
line2
<<<<< HEAD
line3b
line4c
line5d
||||||| 4ddccc1 ... b
line3b
line4
line5
=======
line3
line4
line5
>>>>>>>父母的4ddccc1 ... b
这里是从第3行开始的部分:
- 等于
line3 -line4 -line5
in'theirs'===>> ;>
,它是b
或提交a
的父项) li>
- 等于
line3b-line4 -line5
在提交b
(original section <$ c
- 等于
line3b-line4c-line5d $ c $>
,在merge / revert之前) c>HEAD
'我们的'<<< |||
三种不同的内容,合并无法知道该怎么做。 / p>
I am having trouble with the
git revert
command. I use Ubuntu 12.04 Linux and Git version 1.7.9.5.- I have created a brand new
b_test_repo
on my local PC, having it tracked from a remoteorigin b_test_repo
. - I have created locally a single file (commit
A
) with two lines of text and successfully committed it only in the localmaster
branch.
In order to try out
git revert
I generated 3 more commits, each of them adding one line of text. So mymaster
commit history looks like:A - B - C - D
Where
A
- new file with lines 1 & 2B
- one line addedC
- one line addedD
- one line added
After all these commits the file contained 5 lines:
line1 line2 line3 line4 line5
Then, I wanted to revert commit
B
, which would render the file withoutline3
, which was added by commitB
:git status # On branch master nothing to commit (working directory clean)
I type:
git revert -n master~2
to revert the effect of commit
B
without committing the changes, but get the following:error: could not revert 1a13ad6... Adding one line 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'
I am puzzled why I am getting a conflict, i.e. why does Git have a problem figuring out what it needs to change in the file.
What am I missing here? Please enlighten me!
解决方案Removing that line will generate a conflict with later versions which would change the same line.
So as mention in "What should I do when git revert aborts with an error message?", you need to resolve the merge, add and commit.
A simpler way to revert that commit would be an interactive rebase:
git rebase -i <SHA1 commit a>
And you drop the commit
b
.
But that is valid only if you didn't already pushed your branch to an upstream repo, because it does rewrite the history of commits.If you did already push, then
git revert
is the right approach, in order to generate a new commit cancellingb
(and push that new commit on the upstream repo).
In details: your example generates the following merge conflict:
C:\Users\VonC\prog\git\tests\18779372\r1>git lg * 10b9953 - (HEAD) * 07fff99 - c * 3d888c4 - b * 8c7155f - a
(
git lg
is an alias for a fancygit log
)If there is a conflict, I prefer seeing both the source (theirs), destination (ours) and the original section as before a merge or revert:
git config merge.conflictstyle diff3
Then revert:
git revert -n master~2
That would give:
line1 line2 <<<<<<< HEAD line3 line4 line5 ||||||| 3d888c4... b line3 ======= >>>>>>> parent of 3d888c4... b
That way, you see what
git revert
does: a merge between:- the parent of commit
b
(which obviously doesn't containb
modification) - and
HEAD
The merge cannot decide what do for the section starting with third line:
- the section doesn't exist in
a
(the=== >>>>
part: 'theirs' side) - it is modified in
b
(original part between||||
and====
, as beforerevert
, with justline3
) - and it is also modified in
HEAD
(the<<<< ||||
part, with the addition ofline4
andline5
, even thoughline3
looks unchanged)
The merge conflict is even clearer if you start with commit
a
as:line1 line2 line3 line4 line5
And end up with commit
d
as:line1 line2 line3b line4c line5d
(commit
b
add 'd
' to line3, commitc
adds 'c
' to line 4, commitd
adds 'd
' to line 5)Then a revert will give you:
git config merge.conflictstyle diff3 git revert -n master~2 cat afile.txt line1 line2 <<<<<<< HEAD line3b line4c line5d ||||||| 4ddccc1... b line3b line4 line5 ======= line3 line4 line5 >>>>>>> parent of 4ddccc1... b
Here the section starting at line3:
- equals
line3 -line4 -line5
in 'theirs'=== >>>
, which is the parent ofb
, or commita
) - equals
line3b-line4 -line5
in commitb
(original section||| ===
, before merge/revert) - equals
line3b-line4c-line5d
inHEAD
'ours'<<< |||
Three different contents, and no way for the merge to know what to do.
这篇关于Git恢复不能按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- 等于
-