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

时间:2017-06-23 18:22:08

标签: git undo

首先,我之前已经看到过这个问题的答案,但它被许多“答案”所掩盖,这些答案没有正确回答我的问题,我再也找不到了。

所以这就是:我如何将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'

4 个答案:

答案 0 :(得分:9)

简单&#34; checkout提交&#34;。这将使用您从历史记录中指定的repo快照(提交)覆盖当前工作目录,并将其设置为您可以根据需要进行分段和提交的新工作集。如果您之后立即commit,那么您的repo将具有与您执行checkout的提交相同的文件系统内容(假设您没有其他未分级或暂存的更改)

这将重写历史记录,也不会编辑或删除任何先前的提交 - 因此它类似于&#34; rollback&#34;在Mediawiki上:

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

关于.(点)

.(点)字符表示&#34;当前目录&#34; - 它不是git的特殊或独特之处,它是Windows,Linux,macOS甚至MS-DOS上的标准命令行文件系统约定。它的工作方式类似于..的含义&#34;父目录&#34;。我建议阅读这些:

关于checkout

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

答案 1 :(得分:0)

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

git revert HEAD~1

答案 2 :(得分:0)

修改:我发现您要保留历史记录,因此我的答案无效。但是,它仍然有用。您可以在编辑器中重新排序行,然后继续。

现在,回到原来的答案。

您可以尝试使用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

答案 3 :(得分:-1)

记下当前HEAD的提交哈希

  1. git reset --hard <old-commit>
  2. git reset --soft <previous-HEAD>
  3. `git add。 && git commit -m“消息”

完成!