git revert 到底是做什么的?

What exactly git revert does?

我想找出 git resetgit revertgit checkout 之间的区别。关于 git 还原,我有些不明白。

我制作了一个简单的应用程序并触摸了 2 个文件:file1.html.erbfile2.html.erb,然后我随后创建了 4 个提交:

commit #1: 在 file1.html.erb
的第一行添加一些代码 commit #2: 在 file1.html.erb
的第二行添加一些代码 commit #3: 在 file1.html.erb
的第三行添加一些代码 提交 #4:在 file1.html.erbfile2.html.erb

的第四行添加一些代码

基于以上案例:


git结帐

如果我执行 git checkout HEAD~2,本地文件将返回到提交 #1 的状态,如果我检出到之前的 HEAD,则不会有任何改变。


git 恢复 --hard

git reset HEAD~2 --hard 这会改变提交历史和本地文件,完全回到提交 #1 的状态。 --mixed 会更改提交历史和暂存快照,而 --soft 只会更改提交历史。


git 还原

当我执行 git revert HEAD~2 时,终端返回了这个:

caven@CavendeMacBook-Pro ⮀ ~/demo/demo ⮀ ⭠ branch01 ⮀ git revert HEAD~2 error: could not revert ed3279f... commit 2 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' ✘ caven@CavendeMacBook-Pro ⮀ ~/demo/demo ⮀ ⭠ branch01± ⮀

并且在 file1.html.erb 中,git 将代码标记为:

I add this line at first commit.
<<<<<<< HEAD
I add this line at second commit.
I add this line at third commit.
Simultaneously, I add this line and some code in file2 at fourth commit.
=======
>>>>>>>    parent of ed3279f... commit 2

但是在file2.html.erb中没有任何变化,我在第四次提交时添加的代码仍然存在并且git没有标记任何冲突。

这让我很困惑,git docs 说 "Given one or more existing commits, revert the changes that the related patches introduce, and record some new commits that record them."


我有 3 个问题:

  1. 在这种情况下,git revert 到底在做什么?它只是比较当前状态和指定提交状态之间的差异,然后标记冲突吗?
  2. 我没有指定任何文件,为什么git只在file1中标记冲突,file2呢? git 将如何处理?
  3. 下一步我应该做什么?我应该删除冲突代码并创建一个新的提交吗?或者我应该做其他事情吗?

非常感谢!

Revert 正在尝试删除 修订版 HEAD~2 上执行的更改,并且与应用任何补丁一样,它会产生冲突。 无冲突保证结果的唯一修订将是HEAD(如果它不是合并提交),但其他修订可能 会产生冲突(如果他们弄乱了在您要还原的代码之后修改的代码。如果涉及的代码此后没有被修改过,那么它可能会被还原干净利落)。恢复完成后,将创建一个新的修订版(这与签出和重置不同)。

所以 reset --hard X 表示 "move my HEAD, index, and work tree to the state of X (along with the current branch ref if applicable), the X in git revert X is not a commit whose state you want to return to; it's a commit whose changes should be " 未完成。

换句话说,git revert HEAD~2 的意思是“创建一个与 HEAD~2 所做的相反的补丁,并从中创建一个新的提交以附加到 HEAD

在您的情况下,HEAD~2 在文件 1 的第 2 行添加了一些代码,因此补丁将删除该代码。但是 git 注意到该行的其他代码 "too close for comfort" 自 HEAD~2 发生以来发生了变化,因此它称之为冲突。