git revert:即使在一个简单的情况下也无法撤消单个提交
为了尝试和了解git revert
,我对文本文件做了一系列4个简单的提交--A,B,C,D - foo.txt
目的是稍后撤销提交B并保持提交A,C,D完好无损。git revert:即使在一个简单的情况下也无法撤消单个提交
因此,在每次提交时,我都在文件中添加了一行,模拟添加的功能或引入的错误。
提交后A,中foo.txt
内容:
Feature A
提交B之后,中foo.txt
内容:(在这里,我介绍一下,我会稍后再试撤消/复原的错误。 )
Feature A
Bug
提交后的C,foo.txt
内容:
Feature A
Bug
Feature C
提交后d的foo.txt
内容:
Feature A
Bug
Feature C
Feature D
现在,撤消提交B的影响(其推出的bug),我所做的:
git revert master^^
我想要发生的是,一个新的提交E从文件中删除Bug
行,将文件保留经济需求为:
Feature A
Feature C
Feature D
但是,我得到了错误:
error: could not revert bb58ed3... Bug introduced
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'
与文件的下列不成功git revert
存在的内容:
Feature A
<<<<<<< HEAD
Bug
Feature C
Feature D
=======
>>>>>>> parent of bb58ed3... Bug introduced
(bb58ed3是哈希Commit B,'Bug介绍'此提交的评论。)
问:
这到底是怎么回事?
如果即使这样一个简单的单行提交不能自动恢复/撤消,并且必须要求我手动解析,那么我怎么能恢复一个更复杂的提交,其原始开发人员甚至可能是别人!
是否有一组特殊情况下
git revert
会更好适用?
git
看到每个提交的修改列表(我这里简单化的东西),并试图“不应用”,当你调用git revert
。每个更改列表还包含一些上下文以确保更改有意义。例如,如果我们想做出改变是“行之后添加return
10”,它更可能打破东西比“添加return
线10后,如果行7-9含有X,Y和Z”。因此,我们可以描述你的第二次提交(再次,简化这一点):
- 假设文件的第一行是
Feature A
。 - 假设没有第二线。
- 使第二行包含
Bug
。
您添加后几行中,Bug
的情况下显著变化,所以git revert
是不知道这是否可以简单地将其清除。也许新添加的行实际上修复了错误。所以它要求你明确地解决上下文的冲突。
至于你的问题2-3:是的,git revert
是可用的情况下,当你恢复了一块文件的哪个从那时起没有改变。例如,该错误在foo
函数被引入,但此后仅bar
函数(它位于下面十条线)作了修改。在这种情况下,git revert
很可能会自动恢复更改,因为它认为上下文未更改。
UPD:这里就是为什么即使背景下,如果你想恢复自己的代码中重要的一个例子:
提交A(介意输入错误):
int some_vlue = 0;
read_int_into(some_vlue);
some_vlue = some_vlue++;
提交B(错误引入的):
int some_vlue = 0;
some_vlue = 123;
some_vlue = some_vlue++;
提交C(固定名称):
int some_value = 0;
some_value = 123;
some_value = some_value++;
现在,为了恢复提交B,必须有一些上下文,因为我们不能简单地用旧行read_int_into(some_vlue)
来代替some_value = 123
- 这将是编译错误。
我认为,上下文的是伤害比帮助更多。 'git'应该允许通过'git revert'选项禁用上下文的使用。当您发送补丁并盲目应用补丁或者不知道补丁是否应用于正确的目标及其版本时,上下文会很有用。但在像我这样的情况下,'git'本身准确地知道确切的源和目标,所以为什么要使用上下文,我想知道!欣赏你的解释,顺便说一句。在最后标记之前,我会再等一等。 – Harry
@哈里我已经添加了一些解释。使用变量重命名和方法重命名可能会出现更复杂的情况,并且在某些情况下,最终的代码甚至可以编译。所以,不可能自动检查我们是否可以忽略上下文,'git'是否安全。 – yeputons
你的例子绝对有道理。但是,那么'git'怎么可能依赖(有限的)上下文,因为重命名可以在上下文之外发生? – Harry