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

How do I restore a previous version as a new commit in Git?

首先,我以前在这里看到过这个问题的答案,但是被很多"answers"埋没了,没有正确回答我的问题,我找不到了。

所以它是这样的:如何在 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 提交”。这将使用历史记录中指定的回购快照(提交)覆盖您当前的工作目录,并使其成为您可以根据需要暂存和提交的新工作集。如果您之后立即 commit 那么您的回购将具有与您执行 checkout 的提交相同的文件系统内容(假设您没有其他未暂存或暂存的更改)

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

cd ~/git/your-repo-root
git log
# find the commit id you want
git checkout <commitId> . 
# IMPORTANT NOTE: the trailing `.` in the previous line is important!
git commit -m "Restoring old source code"

另请参阅:Rollback to an old Git commit in a public repo

关于.(点)

.(点)字符表示 "current directory" - 它不是 git 的任何特殊或独特之处,它是一个标准的命令行文件系统约定,与 Windows、Linux、macOS,甚至 MS-DOS。它的工作原理类似于 .. 意味着 "parent directory"。我推荐阅读这些:

关于 checkout

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

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

git revert HEAD~1

编辑:我看到你想保留历史,所以我下面的回答作废。但是,它仍然有用。您可以在编辑器中重新排列行,然后继续。

现在,回到原来的答案。

你可以试试 rebase 命令。

git rebase -i HEAD~n

其中 n 大约比当前提交数和要恢复到的提交数之间的提交数多 1。比方说,删除最后 3 次提交:

git rebase -i HEAD~4

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

在 VIM 中将是 esc 并键入 :exit enter.

现在,只需按下它。这将导致错误,所以强制推送。

git push -f

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

这个方法完全删除了错误的提交,所以它不会只是添加一个带有还原更改的新提交。

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

记下当前 HEAD 的提交哈希

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

完成!