git revert:为什么我会遇到冲突?

Cra*_*hax 3 git

我用Git,我知道:

git revert <hash-code>
Run Code Online (Sandbox Code Playgroud)

用于创建一个新的提交,它将与哈希代码中的过去提交相同.例如,我有以下提交:

1f74a0e second commit
e72d8b8 first commit  
Run Code Online (Sandbox Code Playgroud)

我想恢复第一次提交,所以我使用了:

git revert 1f74a0e
Run Code Online (Sandbox Code Playgroud)

不过,我收到以下错误:

错误:无法恢复1f74a0e ...首先提交提示:解决冲突后,标记更正的路径提示:使用'git add'或'git rm'提示:并使用'git commit'提交结果

至于冲突,我输入:

$ git diff --name-only --diff-filter=U
file.txt
Run Code Online (Sandbox Code Playgroud)

当我打开file.txt时,我看不到任何冲突的迹象.

当然会有冲突.我希望git采取"第一次提交"并将其复制到第二次提交之上.我该怎么做?

Edw*_*son 10

这实际上不是还原的作用.Revert没有"带你回去"提交并假装后续提交没有发生.它应用单个提交的逻辑否定 - 并且单独提交 - 留下后续提交.

假设你有一些文件的初始提交 - 为简单起见,我们称之为提交#1,文件如下所示:

One
Two
Three
Four
Run Code Online (Sandbox Code Playgroud)

现在让我们假设您有一个更改一行的提交#2:

One
2
Three
Four
Run Code Online (Sandbox Code Playgroud)

最后,提交更改不同行的#3:

One
2
Three
4
Run Code Online (Sandbox Code Playgroud)

如果您尝试还原提交#2,它将仅撤消该提交中更改的行,并保留提交#3中引入的更改,因此结果将是:

One
Two
Three
4
Run Code Online (Sandbox Code Playgroud)

现在,如果有后续提交更改了与您尝试还原的提交相同的行,那么您将发生冲突.例如,假设你有一个提交#4也改变了第二行:

One
TWO
THREE
4
Run Code Online (Sandbox Code Playgroud)

现在,如果您的HEAD是#4提交并且您尝试还原提交#2,则会发生冲突.Revert期望返回第二行 - 撤消commit#2中所做的更改.所以它期望第二行当前是2,然后它将它恢复到之前的提交中,将其设置为Two.

但是,由于提交#4 改变了它,因此该期望无效.所以你有冲突.

如果你的目标不是要恢复,而是回到提交#1并忽略从那时起所做的所有更改,那么你想要reset而不是revert.

git reset --hard 1 
Run Code Online (Sandbox Code Playgroud)

  • 如果我有大量的提交需要恢复(而不是重置),其中包括单独的冲突,但放在一起时则不然,该怎么办?换句话说,假设我想恢复最后 100 次提交,所以我执行 `git revert 531a..HEAD`。我如何进行大规模恢复并避免 git 希望我按顺序解决的虚假冲突? (8认同)

Dio*_*ogo 7

我正在补充@Edward 的答案。首先,恢复命令要求“您的工作树是干净的(没有来自 HEAD 提交的修改)”(请参阅​​此处的文档)。revert命令将恢复给定提交的更改,并将您当前的状态与您要恢复其更改的提交的父级状态进行比较。如果当前状态与 PARENT 冲突,git 会指出这一点。如果没有,你就不会发生冲突。

这是一个基于@Edward 的示例:

假设您有 3 个修改文件的提交:

commit1:

One
Two
Run Code Online (Sandbox Code Playgroud)

commit2

One
2       # < we introduced this changed in commit 2
Run Code Online (Sandbox Code Playgroud)

commit3

One
2
three   # < we introduced this change in commit 3
Run Code Online (Sandbox Code Playgroud)

如果您从当前状态恢复提交 2 引入的更改(提交 3,假设清除 3,即 HEAD 提交没有修改),git 将

  1. 删除由此引入的修改commit 2,改2two
  2. three保留引入的行commit 3。不会发生冲突,因为当前状态 ( ) 与我们要恢复其更改 ( ) 的提交的父级 ( )commit 3不冲突commit 1commit 2

现在,假设您有不同的情况:

commit1:

One
Two
three
Run Code Online (Sandbox Code Playgroud)

commit2

One
2       # < we introduced this changed in commit 2
three
Run Code Online (Sandbox Code Playgroud)

commit3

One
2
3   # < we introduced this change in commit 3
Run Code Online (Sandbox Code Playgroud)

如果您commit 2从当前状态恢复由 引入的更改(commit 3,假设明确三个,即没有来自 HEAD 提交的修改),git 将

  1. 删除提交 2 引入的修改,改2回 2`
  2. 将引入的行commit 3与其父级进行比较commit 2并指示冲突:该行three更改3为我们要恢复其更改的提交(提交 2)的父级(提交 1)并与之冲突

  • 你的第二个例子和@Edward的第一个没有冲突的例子有什么区别? (2认同)

hsp*_*her 0

很可能您的索引中已经存在未解决的冲突,可能是因为中间留下了某些合并,或者恢复本身导致了冲突。无论如何,您需要解决冲突并提交。

git status
# You would find files with conflicts
# resolve the commits

git add -u
git commit
Run Code Online (Sandbox Code Playgroud)