为了账号安全,请及时绑定邮箱和手机立即绑定

使用暂存区域中的未提交文件撤消git reset --hard

使用暂存区域中的未提交文件撤消git reset --hard

Git
互换的青春 2019-08-16 14:25:36
使用暂存区域中的未提交文件撤消git reset --hard我正在努力恢复我的工作。我愚蠢地做了git reset --hard,但在那之前我只做过get add .而且没做过git commit。请帮忙!这是我的日志:MacBookPro:api user$ git status# On branch master# Changes to be committed:#   (use "git reset HEAD <file>..." to unstage)#   modified:   .gitignore...MacBookPro:api user$ git reset --hardHEAD is now at ff546fa added new strucuture for apigit reset --hard在这种情况下可以撤消吗?
查看完整描述

3 回答

?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

您应该能够恢复添加到索引中的任何文件(例如,在您的情况下git add .),尽管它可能有点工作。为了将文件添加到索引,git将它添加到对象数据库,这意味着只要尚未发生垃圾收集,它就可以恢复。在JakubNarębski的答案中有一个如何做到这一点的例子:

  • 执行git reset后恢复添加的文件--hard HEAD ^

但是,我在测试存储库上尝试了这一点,并且存在一些问题 - --cached应该是--cache,并且我发现它实际上并没有创建.git/lost-found目录。但是,以下步骤对我有用:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")

这应该输出对象数据库中的任何ref,索引或reflog都无法访问的所有对象。输出看起来像这样:

unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03

......对于每个blob,你可以这样做:

git show 907b308

输出文件的内容。


输出太多了?

更新响应sehe以下的评论:

如果您发现该命令的输出中列出了许多提交和树,您可能希望从输出中删除任何从未引用的提交引用的对象。(通常你可以通过reflog回到这些提交 - 我们只对已添加到索引但永远无法通过提交找到的对象感兴趣。)

首先,保存命令的输出,使用:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all

现在可以找到那些无法访问的提交的对象名称:

egrep commit all | cut -d ' ' -f 3

因此,您可以找到已添加到索引但未在任何时间提交的树和对象,具有:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
  $(egrep commit all | cut -d ' ' -f 3)

这极大地减少了你必须考虑的物体数量。


更新: 下面的Philip Oakley提出了另一种减少要考虑的对象数量的方法,即只考虑最近修改过的文件.git/objects。你可以找到这些:

find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort

(我在这里发现了这个find调用。)该列表的结尾可能如下所示:

2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a

在这种情况下,您可以看到这些对象:

git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a

(请注意,您必须删除/路径末尾的内容才能获取对象名称。)


查看完整回答
反对 回复 2019-08-16
?
临摹微笑

TA贡献1982条经验 获得超2个赞

我只是做了一个git reset --hard并丢失了一个提交。但我知道提交哈希,所以我能够做git cherry-pick COMMIT_HASH来恢复它。

我在丢失提交的几分钟内就这样做了,所以它可能适合你们中的一些人。


查看完整回答
反对 回复 2019-08-16
?
心有法竹

TA贡献1866条经验 获得超5个赞

首先,我将所有哈希保存到文件中:


git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > allhashes

接下来我将它们全部放入(删除'无法访问的blob'的东西)列表并将数据全部放入新文件中...你必须选择你的文件并重新命名它们你需要...但我只需要一些files..hope这有助于某人......


commits = ["c2520e04839c05505ef17f985a49ffd42809f",

    "41901be74651829d97f29934f190055ae4e93",

    "50f078c937f07b508a1a73d3566a822927a57",

    "51077d43a3ed6333c8a3616412c9b3b0fb6d4",

    "56e290dc0aaa20e64702357b340d397213cb",

    "5b731d988cfb24500842ec5df84d3e1950c87",

    "9c438e09cf759bf84e109a2f0c18520",

    ...

    ]


from subprocess import call

filename = "file"

i = 1

for c in commits:

    f = open(filename + str(i),"wb")

    call(["git", "show", c],stdout=f)

    i+=1


查看完整回答
反对 回复 2019-08-16
  • 3 回答
  • 0 关注
  • 1004 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信