是否有可能撤销的改变而引起的以下命令?如果是这样,怎么样?

git reset --hard HEAD~1
有帮助吗?

解决方案

帕特Notz是正确的。你可以得到的承诺回来,只要它已经在几天之内。git只有垃圾收集大约一个月以后或所以除非你明确地告诉它删除新的斑点。

$ 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中除去的结果作为难重,但是放回原处的时候我通过这种情况。

其他提示

什么你想要做的就是指定sha1的承诺要恢复。你可以得到的sha1通过审查这种情况(git reflog)和然后在做

git reset --hard <sha1 of desired commit>

但是,不要等待的太久...几个星期之后发生了错误,最终看到,提交作为未引用,并删除所有的斑点。

答案是隐藏在详细答复所述,可以简单地这样做:

$> git reset --hard HEAD@{1}

(见的输出 git种情况显示)

它可以恢复如果它Git没有垃圾收集。

概览的晃来晃去的提交 fsck:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

恢复晃来晃去的承诺与衍合:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

如果你真的很幸运,好像我是,你可以回到你的文本编辑器和打'撤销'.

我知道那不是真的一个适当的答案,但它救了我一半一天的工作,所以希望它会这样做别人!

例IRL的情况:

$ git fsck --lost-found

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

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <stian@Stians-Mac-mini.local>
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*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.

据我所知, --hard 会丢弃的未提交的变化。由于这些不是跟踪的饭桶。但你可以撤消的 discarded commit.

$ git reflog

将清单:

b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....

哪里 4bac331 是的 discarded commit.

现在只是头移动到,提交:

$ git reset --hard 4bac331

在大多数情况下,是的。

取决于国家是在当运行该命令的影响 git reset --hard 可能范围从微不足道,以消除,基本上是不可能的。

下面我们列出了一系列不同的可能情况,以及如何可能恢复从他们。

我所有的更改承诺,但是现在的犯都不见了!

这种情况通常发生在运行 git reset 有一种论点,因为在 git reset --hard HEAD~.不要担心,这是易于恢复!

如果你只跑了 git reset 和什么都没做别人因为,你可以回到哪里你是这个衬:

git reset --hard @{1}

这是重新设置你的当前分支的任何国家,它在之前的最后一次修改(在你的情况,最近的修改,以支将难重你都在试图撤消).

但是,如果你 做出其他的修改分支机构由于重置,一个衬垫上面不会工作。相反,你应该跑 git reflog <branchname> 看到一个列表中的所有最近的变化作出分支(包括重置).这名单看起来是这样的:

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

找到的操作,这个列表中,你想到"撤消"。在上面的例子,它将第一行,一个是说"重置:移动到头~".然后再复制所表示的承诺 之前 (下文),操作。在我们的情况,那将是 master@{1} (或 3ae5027, 他们都表示同样的承诺),并运行 git reset --hard <commit> 要重设你的当前分支回,提交。

我上演我的变化 git add, 但从来没有承诺。现在我的更改都不见了!

这是一个有点棘手恢复。git 有文件的副本,你加入,但由于这些副本从来都不依赖于任何特定承诺你不能恢复的变化。不,你必须找到这个文件在git的数据库,并恢复他们。你可以这样做使用 git fsck.

详情,请参阅 撤消git重置--硬与未提交的文件中的临时区域.

我已经改变的文件,在我的工作目录我从不上演着 git add, 和永远的承诺。现在我的更改都不见了!

呃...哦。我讨厌告诉你这个,但你也许不走运。git不存储的变化,你没有添加或承诺,并根据 文档 git reset:

-硬

重指数和工作树。 任何的改变,以跟踪文件的工作树因为 <commit> 被丢弃。

这有可能是你 可能会 可以恢复你的改变与某种形式的磁盘上恢复公用事业或专业的数据恢复服务,但在这一点上,这可能是更多的麻烦比它的价值。

如果你有没有垃圾收集储存库(例如使用 git repack -dgit gc, 但注意,垃圾收集还可以自动发生的),然后提交是仍然有–这就不再可通过头。

你可以试着找到你的承诺,通过寻找通过的输出 git fsck --lost-found.

较新版本,内有一些所谓的"种情况",这是一个记录的所有更改作出的裁判(而不是改变,这是由于存储库的内容)。因此,举例来说,每一次你换你的头(即每次你做一个 git checkout 关分支机构),这将被记录。当然,你 git reset 还操纵的头上,因此也有记录。你可访问旧的国家的裁判在一个类似的方式,可访问旧国的仓库,通过使用 @ 标志,而不是一个 ~, 样 git reset HEAD@{1}.

我花了一段时间了解之间有什么区别的头@{1}而头~1,那么这一点解释:

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

所以, HEAD~1 意味着"转到提交之前提交的头目前点",同时 HEAD@{1} 意味着"转到提交这头指出在之前指出,在它当前点".

这会很容易让你找到丢失的承诺,并恢复它。

我知道这是一个旧线...但是,正如许多人是寻找方法来撤消的东西更新我仍然认为这可能是一个好主意继续给予提示在这里。

当你做一个"混帐添加"或移动任何东西从左上到底左在git gui文件的内容存储在一个blob和文件内容能够恢复,blob。

因此,它是可能恢复文件,即使它不是致力但它已经已经增加。

git init  
echo hello >> test.txt  
git add test.txt  

现在blob是创建,但是所引用的索引,因此它将不会列}类的直到我们的复位。因此,我们重...

git reset --hard  
git fsck  

你会得到一晃来晃去的blob ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

会给你的文件的内容"hello"回

找到未引用的提交我发现了一个尖端的某处表明这一点。

gitk --all $(git log -g --pretty=format:%h)  

我把它作为一种工具,在git gui,这是非常方便。

在回答前让我们添加一些背景,解释这是什么 HEAD.

First of all what is HEAD?

HEAD 只是一个参照目前的承诺(新)在当前的分支。
只能有一个 HEAD 在任何给定的时间。(不包括 git worktree)

的内容 HEAD 是内部保存的 .git/HEAD 它包含40个字节SHA-1的前提交。


detached HEAD

如果你是不是在最新提交的意义, HEAD 是指向一个前提交其所谓的历史 detached HEAD.

enter image description here

在命令行它看起来会像这样-SHA-1而不是分由于名字 HEAD 不是指向的尖端当前的分支

enter image description here


几项关于如何恢复从一个独立的头:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

这将结账新的分支指的所需的承诺。
这种命令将结账到给予提交。
在这一点上你可以创建一个分支,并开始工作,从这一点。

# 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>

git reflog

你可以随时使用 reflog 为好。
git reflog 将显示任何改变,它更新了 HEAD 并检查了所需的种情况的条目将设置 HEAD 回到这个承诺。

每次的头修改将有一个新的条目 reflog

git reflog
git checkout HEAD@{...}

这会让你回到你想要的承诺

enter image description here


git reset HEAD --hard <commit_id>

"移动"你的头回所需的承诺。

# 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.
  • 注:(由于Git2.7)
    你也可以使用 git rebase --no-autostash 为好。


git revert <sha-1>

"撤销"给定的承诺或承诺的范围。
Reset命令将"撤消"中所做的任何更改给予提交。
一个新的提交与撤消贴将提交时的原始提交将保持在历史记录。

# 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>

这个架构说明其命令做什么。
正如你可以看到有 reset && checkout 修改 HEAD.

enter image description here

我只是做了一个难重在错误的项目。什么救了我的生活是蚀本地的历史。Idea是说有一个,太,所以你可以编辑,这是值得检查:

  1. 日蚀有帮助的话题在当地的历史
  2. http://wiki.eclipse.org/FAQ_Where_is_the_workspace_local_history_stored%3F

做了一个小小的脚本,使它稍微比较容易找到的提交人是在寻找:

git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'

是的,它可以大大漂亮awk或类似的东西,但是很简单我只是需要它。可能拯救其他人的30秒钟。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top