如何在不删除最新提交的情况下恢复到之前的提交?

问题描述

假设我有 2 个提交,我已经推送到我的远程分支。

  • 提交 A(2021 年 5 月 31 日)
  • 提交 B(2021 年 5 月 30 日)

如何在不删除提交 A 的情况下恢复到提交 B?我只想比较这 2 个提交之间的结果。

注意:不需要代码比较。我只想比较 Commit A 与 Commit B 的输出

解决方法

我非常不同意其他建议您使用 git revert 的答案。这实际上会真正还原 Commit A 引入的更改并自行生成提交。

由于您想查看某个时间点的状态,您可以直接签出 Commit B 以便检查内容。然后签出原始分支以返回到最新的提交。

git checkout $HASH_OF_COMMIT_B   # now you are in a detached head state at commit B
git checkout $BRANCH             # now you are back at the tip of the branch (commit A)

很多工具可以让你直接看到两个引用之间的区别,而无需结账。在命令行上,这可以通过 git diff:

完成
git diff $HASH_OF_COMMIT_A..$HASH_OF_COMMIT_B
,

如何在不删除提交 A 的情况下恢复到提交 B?

您可以轻松使用git rebase -i <commit_hash>

  • 在提交 B 之前选择一个提交,即提交 C

HEAD

  • git rebase -i <commit_hash_commitC>
  • 以上命令将在您的文本编辑器中列出提交,如下所示:
pick f7f3f6d Commit B
pick a5f4a0d Commit A

# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p,pick <commit> = use commit
# r,reword <commit> = use commit,but edit the commit message
# e,edit <commit> = use commit,but stop for amending
# s,squash <commit> = use commit,but meld into previous commit
# f,fixup <commit> = like "squash",but discard this commit's log message
# x,exec <command> = run command (the rest of the line) using shell
# b,break = stop here (continue rebase later with 'git rebase --continue')
# d,drop <commit> = remove commit
# l,label <label> = label current HEAD with a name
# t,reset <label> = reset HEAD to a label
# m,merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline,if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However,if you remove everything,the rebase will be aborted.
#
# Note that empty commits are commented out
  • 删除代表 Commit B 的行,然后保存并退出文本编辑器。
  • Git 将重播交互式编辑器中提到的所有提交并停止,这将完全删除提交 B。
,

您可以进行交互式 rebase,删除不需要的提交,并对删除分支进行强制推送。

git rebase -i     //opens interactive rebasing window

pick #commitID2 My commit 2
pick #commitID1 My commit 1    <- To unpick/remove this commit,using editor remove 
                                  line->

save the window.
git push origin branchname -f 
,

还原提交 B 不会删除 提交 A。它只会创建 提交 C,这将撤消您在 中所做的一切提交 B

git revert commit-b-hash
,
git revert <Commit B>

给定一个或多个现有提交,还原相关补丁引入的更改,并记录一些记录它们的新提交。这需要你的工作树是干净的(没有来自 HEAD 提交的修改)。 git docs


但是,如果您只是想看看两者之间的区别:

git diff <Commit B>..<Commit A>

显示工作树和索引或树之间的更改、索引和树之间的更改、两棵树之间的更改、合并导致的更改、两个 blob 对象之间的更改或磁盘上两个文件之间的更改。 git docs