How can I undo git reset --hard HEAD~1?
是否可以撤消由以下命令引起的更改?如果是,如何?
1 | git reset --hard HEAD~1 |
帕特·诺茨是对的。只要几天之内,你就可以取回承诺。Git只在大约一个月后收集垃圾,除非您明确告诉它删除新的blob。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | $ git init Initialized empty Git repository in .git/ $ echo"testing reset"> file1 $ git add file1 $ git commit -m 'added file1' Created initial commit 1a75c1d: added file1 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file1 $ echo"added new file"> file2 $ git add file2 $ git commit -m 'added file2' Created commit f6e5064: added file2 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file2 $ git reset --hard HEAD^ HEAD is now at 1a75c1d... added file1 $ cat file2 cat: file2: No such file or directory $ git reflog 1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD f6e5064... HEAD@{1}: commit: added file2 $ git reset --hard f6e5064 HEAD is now at f6e5064... added file2 $ cat file2 added new file |
您可以在示例中看到,由于硬重置,文件2被删除,但当我通过reflog重置时,它被放回原位。
您要做的是指定要还原到的提交的sha1。您可以通过检查reflog(
江户十一〔一〕号
但不要等太久…几周后,Git最终会将提交视为未引用,并删除所有blob。
答案隐藏在上面的详细响应中,您可以简单地执行以下操作:
1 | $> git reset --hard HEAD@{1} |
(见git reflog show输出)
如果Git还没有收集到垃圾,则可以恢复它。
了解与
1 2 | $ git fsck --lost-found dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf |
号
使用REBASE恢复挂起的提交:
1 | $ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf |
如果你真的很幸运,像我一样,你可以回到你的文本编辑器,点击"撤销"。
我知道这不是一个正确的答案,但它节省了我半天的工作,所以希望它能为别人做同样的事情!
据我所知,
1 | $ git reflog |
遗嘱清单:
1 2 3 | b0d059c HEAD@{0}: reset: moving to HEAD~1 4bac331 HEAD@{1}: commit: added level introduction.... .... |
。
其中
现在,只要把头移到那个任务上:
1 | $ git reset --hard 4bac331 |
IRL案例示例:埃多克斯1〔13〕
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Checking object directories: 100% (256/256), done. Checking objects: 100% (3/3), done. dangling blob 025cab9725ccc00fbd7202da543f556c146cb119 dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4 dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98 dangling blob 9183b84bbd292dcc238ca546dab896e073432933 dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22 dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7 dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66 dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b dangling blob b87163c8def315d40721e592f15c2192a33816bb dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7 dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133 dangling blob 4a71f9ff8262701171d42559a283c751fea6a201 dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2 dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed dangling blob 749ffc9a412e7584245af5106e78167b9480a27b dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a <- it's this one |
。埃多克斯1〔14〕
1 2 3 4 5 6 7 8 9 10 11 12 | commit f6ce1a403399772d4146d306d5763f3f5715cb5a Author: Stian Gudmundsen H?iland <[email protected]> Date: Wed Aug 15 08:41:30 2012 +0200 *MY COMMIT MESSAGE IS DISPLAYED HERE* diff --git a/Some.file b/Some.file new file mode 100644 index 0000000..15baeba --- /dev/null +++ b/Some.file *THE WHOLE COMMIT IS DISPLAYED HERE* |
。埃多克斯1〔15〕
1 2 | First, rewinding head to replay your work on top of it... Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a. |
在大多数情况下,是的。
根据运行该命令时存储库所处的状态,
下面我列出了一系列不同的可能场景,以及您如何从中恢复。
我的所有更改都已提交,但现在提交已不复存在!这种情况通常发生在使用参数运行
如果您刚刚运行
1 | git reset --hard @{1} |
这将重置当前分支,无论它在上次修改之前处于何种状态(在您的情况下,对分支的最新修改将是您尝试撤消的硬重置)。
但是,如果您在重置之后对分支进行了其他修改,则上面的一行程序将无法工作。相反,您应该运行
1 2 3 4 | 7c169bd master@{0}: reset: moving to HEAD~ 3ae5027 master@{1}: commit: Changed file2 7c169bd master@{2}: commit: Some change 5eb37ca master@{3}: commit (initial): Initial commit |
号
在此列表中查找要"撤消"的操作。在上面的例子中,它是第一行,上面写着"重置:移动到头部"。然后在该操作之前(下面)复制提交的表示。在我们的情况下,这将是
这是一个比较棘手的恢复。Git确实有您添加的文件的副本,但是由于这些副本从未绑定到任何特定的提交,所以您不能一次恢复所有更改。相反,您必须在Git的数据库中找到各个文件,并手动恢复它们。您可以使用
有关此操作的详细信息,请参阅登台区域中的undo git reset--hard with uncommitted files。
我对工作目录中的文件进行了更改,我从未与哦,哦。我不想告诉你这个,但你可能走运了。Git不存储您没有添加或提交的更改,并且根据
--hard
Resets the index and working tree. Any changes to tracked files in the working tree since
are discarded.
号
有可能您可以使用某种磁盘恢复实用程序或专业的数据恢复服务来恢复更改,但此时这可能比它的价值更麻烦。
如果您还没有垃圾收集您的存储库(例如,使用
您可以通过查看
较新版本的Git有一个称为"reflog"的东西,它是对refs所做的所有更改的日志(而不是对存储库内容所做的更改)。因此,例如,每次您切换您的头(即每次您执行
我花了一段时间才理解head@1和head~1之间的区别,所以这里有一个小小的解释:
1 2 3 4 5 6 7 8 9 | git init git commit --allow-empty -mOne git commit --allow-empty -mTwo git checkout -b anotherbranch git commit --allow-empty -mThree git checkout master # This changes the HEAD, but not the repository contents git show HEAD~1 # => One git show HEAD@{1} # => Three git reflog |
。
因此,
这很容易让您找到丢失的提交并恢复它。
在回答之前,让我们添加一些背景,解释一下这个
如果您没有进行最新的提交,这意味着
。
在命令行上,它看起来像是-sha-1而不是分支名称,因为
氧化镁
关于如何从分离的头部恢复的几个选项:江户十一〔11〕。1 2 3 | git checkout <commit_id> git checkout -b <new branch> <commit_id> git checkout HEAD~X // x is the number of commits t go back |
这将签出指向所需提交的新分支。此命令将签出到给定的提交。在这一点上,您可以创建一个分支并从这一点开始工作。
1 2 3 4 5 6 7 8 | # Checkout a given commit. # Doing so will result in a `detached HEAD` which mean that the `HEAD` # is not pointing to the latest so you will need to checkout branch # in order to be able to update the code. git checkout <commit-id> # create a new branch forked to the given commit git checkout -b <branch name> |
号埃多克斯1〔12〕
您也可以使用
每次修改磁头时,
1 2 | git reflog git checkout HEAD@{...} |
这将使你回到你想要的承诺
氧化镁
埃多克斯1〔18〕"移动"你的头回到想要的承诺。
1 2 3 4 5 6 7 8 9 10 11 | # This will destroy any local modifications. # Don't do it if you have uncommitted work you want to keep. git reset --hard 0d1d7fc32 # Alternatively, if there's work to keep: git stash git reset --hard 0d1d7fc32 git stash pop # This saves the modifications, then reapplies that patch after resetting. # You could get merge conflicts, if you've modified things which were # changed since the commit you reset to. |
。
- 注:(自Git 2.7起)您也可以使用
git rebase --no-autostash 。
埃多克斯1〔20〕
"撤消"给定的提交或提交范围。重置命令将"撤消"在给定提交中所做的任何更改。将提交带有撤销补丁的新提交,而原始提交也将保留在历史记录中。
1 2 3 | # add new commit with the undo of the original one. # the <sha-1> can be any commit(s) or commit range git revert <sha-1> |
这个模式说明了哪个命令执行什么操作。如您所见,
氧化镁
我知道这是一条旧线…但是,随着很多人在寻找在Git中撤销内容的方法,我仍然认为继续在这里提供提示可能是个好主意。
当您在Git GUI中执行"Git添加"或从左上角到左下角移动任何内容时,文件的内容存储在一个blob中,并且可以从该blob中恢复文件内容。
因此,即使没有提交文件,也可以恢复该文件,但必须添加该文件。
1 2 3 | git init echo hello >> test.txt git add test.txt |
。
现在已经创建了blob,但它被索引引用,因此在重置之前,它不会与git fsck一起列出。所以我们重置…
1 2 | git reset --hard git fsck |
您将得到一个悬空的斑点CE013625030BA8DBA906F756967F9E9CA394464A
1 | git show ce01362 |
。
会把文件内容"你好"还给你
为了找到未被引用的承诺,我在某个地方找到了一个建议。
1 | gitk --all $(git log -g --pretty=format:%h) |
号
我在GitGUI中把它作为一个工具使用,它非常方便。
我刚做了一个错误的项目的硬重置。挽救我生命的是Eclipse的本地历史。Intellij的想法据说也有一个,所以你的编辑,这是值得检查的:
制作了一个很小的脚本,使其更容易找到所需的提交:
江户十一〔16〕号
是的,它可以用锥子或类似的东西做得相当漂亮,但它很简单,我只是需要它。可能会节省别人30秒。