首先,我以前在这里看到过这个问题的答案,但它被这么多不能正确回答我的问题的“答案”所掩盖,以至于我无法再次找到它。
所以这里是:如何在 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'
简单地“
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”意味着完全是别的东西)。
编辑:我看到你想保留历史记录,所以我下面的回答无效。然而,它仍然有用。您可以在编辑器中重新排序各行,然后继续。
现在,回到原来的答案。
你可以尝试rebase命令。
git rebase -i HEAD~n
其中
n
大约比当前和要恢复到的提交之间的提交数量多一。比如说,删除最后 3 个提交:
git rebase -i HEAD~4
到达那里后,它将在 VIM 或 Nano(或其他编辑器)中打开。只需删除要删除的提交行,然后退出编辑器即可。
在 VIM 中,这将是
esc
并输入 :exit
enter
。
现在,只需推一下即可。这会导致错误,因此请强制推送。
git push -f
您可能还必须指定分支名称和上游。这样应该就可以了!
此方法完全删除了错误的提交,因此它不会只是添加具有恢复更改的新提交。
记下当前 HEAD 的提交哈希
git reset --hard <old-commit>
git reset --soft <previous-HEAD>
git add . && git commit -m "message"
完成!
使用 git revert https://git-scm.com/docs/git-revert
git revert HEAD~1