如何在 Git 中将以前的版本恢复为新提交?

问题描述 投票:0回答:4

首先,我以前在这里看到过这个问题的答案,但它被这么多不能正确回答我的问题的“答案”所掩盖,以至于我无法再次找到它。

所以这里是:如何在 Git 中恢复到我的历史记录中的先前版本,以便它成为我当前历史记录之上的新提交?

基本上,这是我想用版本控制系统做的最基本的事情。简单地进行重置是行不通的,因为它会丢弃我的历史记录,简单的恢复也不起作用,因为有时它会给我错误消息(我想要做的应该是没有任何错误消息的可能)。

如果我只是执行

git revert
就会发生此错误:

git revert HEAD~1
error: could not revert f1b44e3... Towards translating API to kernel.
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 undo
4个回答
38
投票

简单地“

checkout
提交”。这将使用历史记录中指定的存储库快照(提交)覆盖您当前的工作目录,并使其成为您可以根据需要暂存和提交的新工作集。

cd ~/git/your-repo-root
git log
# find the commit id you want
git checkout <commitId> .

重要提示:上一行中的尾随

.
很重要!如果省略它,您最终将处于“分离的 HEAD”状态,这是您不想要的。

如果您随后立即

commit
,那么您的存储库将具有与您执行
checkout
的提交相同的文件系统内容(假设您没有其他未暂存或暂存的更改):

git commit -m "Restoring old source code"

这将不会重写历史记录,也不会编辑或删除任何以前的提交 - 因此它的工作方式类似于 Mediawiki 上的“回滚”:

另请参阅:回滚到公共存储库中的旧 Git 提交

关于
.
(点)

.
(点)字符的意思是“当前目录”——它对 git 来说并不是什么特殊或独特的东西,它是一个标准的命令行文件系统约定,在 Windows、Linux、macOS 甚至 MS-DOS 上都是相同的。它的工作原理类似于
..
的意思是“父目录”。我建议阅读这些:

关于
checkout

请注意:

checkout
是 git 中的一个重载命令 - 它可能意味着切换分支(
svn switch
)或从历史记录中获取特定文件或提交并放入工作区(
svn update -r <id>
)。它也可能意味着其他事情:https://git-scm.com/docs/git-checkout - 我很高兴它会让人们感到困惑,尤其是当我在使用 TFS 多年后开始使用 git 时(其中“Checkout”意味着完全是别的东西)。


2
投票

编辑:我看到你想保留历史记录,所以我下面的回答无效。然而,它仍然有用。您可以在编辑器中重新排序各行,然后继续。

现在,回到原来的答案。

你可以尝试rebase命令。

git rebase -i HEAD~n

其中

n
大约比当前和要恢复到的提交之间的提交数量多一。比如说,删除最后 3 个提交:

git rebase -i HEAD~4

到达那里后,它将在 VIM 或 Nano(或其他编辑器)中打开。只需删除要删除的提交行,然后退出编辑器即可。

在 VIM 中,这将是

esc
并输入
:exit
enter

现在,只需推一下即可。这会导致错误,因此请强制推送。

git push -f

您可能还必须指定分支名称和上游。这样应该就可以了!

此方法完全删除了错误的提交,因此它不会只是添加具有恢复更改的新提交。

这是文档:https://git-scm.com/docs/rebase


1
投票

记下当前 HEAD 的提交哈希

  1. git reset --hard <old-commit>
  2. git reset --soft <previous-HEAD>
  3. git add . && git commit -m "message"

完成!


0
投票

使用 git revert https://git-scm.com/docs/git-revert

git revert HEAD~1
© www.soinside.com 2019 - 2024. All rights reserved.