如何在不删除最新提交的情况下恢复到上一个提交?
Posted
技术标签:
【中文标题】如何在不删除最新提交的情况下恢复到上一个提交?【英文标题】:How do I revert to the previous commit without deleting the latest commit? 【发布时间】:2021-08-18 19:05:52 【问题描述】:假设我有 2 个提交已经推送到我的远程分支。
提交 A(2021 年 5 月 31 日) 提交 B(2021 年 5 月 30 日)如何在不删除提交 A 的情况下恢复到提交 B?我只是想比较这 2 次提交的结果。
注意:不需要代码比较。我只是想比较 Commit A 和 Commit B 的输出
【问题讨论】:
在 git 中删除提交实际上是不可能的。所以你不应该害怕。 是的有点担心,因为它是生产代码。无论如何,将在我的个人演示项目中尝试“风险更高”的选项 我的意思是,在 git 中没有冒险的方法,因为你的提交永远不会被删除。 git 中没有删除提交的选项,你可以随时取回它。 只签出提交 B? @JawadElFou:有可能会丢失提交,但这需要一些工作——如果你将 Git 存储库连接到另一个 Git 存储库,提交将会返回它。 :-) 【参考方案1】:我强烈不同意建议您使用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
【讨论】:
是的,问题标题中的 revert 会让人误入歧途。旁注:Git 人员正试图让人们远离使用git diff
中的两点符号。任何git diff A..B
总是可以写成git diff A B
,这实际上使命令更短。唯一需要这两个点的地方是,如果您省略 A
或 B
之一以暗示 HEAD
:git diff A..
必须替换为 git diff A @
,这不会使其更短。跨度>
强烈同意。如果您只想比较两个提交的行为,这实际上很简单。只需检查第一个,测试,检查另一个,测试。【参考方案2】:
如何在不删除提交 A 的情况下恢复到提交 B?
您可以轻松使用git rebase -i <commit_hash>
HEAD
git rebase -i <commit_hash_commitC>
上述命令将在您的文本编辑器中列出提交,如下所示:
删除代表提交 B 的行,然后保存并退出文本编辑器。 Git 将重播交互式编辑器中提到的所有提交并停止,这将完全删除提交 B。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
【讨论】:
【参考方案3】:您可以进行交互式变基,删除您不需要的提交,并在您的删除分支上进行硬推送。
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
【讨论】:
【参考方案4】:还原 Commit B 不会删除 Commit A。它只会创建 commit C,这将撤消您在 中所做的一切提交 B
git revert commit-b-hash
【讨论】:
【参考方案5】:git revert <Commit B>
给定一个或多个现有提交,还原相关补丁引入的更改,并记录一些记录它们的新提交。这要求您的工作树是干净的(不修改 HEAD 提交)。 git docs
不过,如果你只是想看看两者的区别:
git diff <Commit B>..<Commit A>
显示工作树和索引或树之间的更改、索引和树之间的更改、两棵树之间的更改、合并导致的更改、两个 blob 对象之间的更改或磁盘上两个文件之间的更改。 git docs
【讨论】:
以上是关于如何在不删除最新提交的情况下恢复到上一个提交?的主要内容,如果未能解决你的问题,请参考以下文章