在暂存区域中使用未提交的文件很难

我正在努力恢复我的工作。 我愚蠢地做了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 --hard
HEAD is now at ff546fa added new strucuture for api

是否有可能撤销git reset --hard在这种情况下很难?


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

  • 完成git reset后恢复添加的文件--hard HEAD ^
  • 不过,我试过了一个测试版本库,并有一对夫妇的问题- --cached--cache ,我发现,它并没有实际创建.git/lost-found目录。 但是,以下步骤适用于我:

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

    这应该输出对象数据库中的所有对象,这些对象无法通过任何引用,索引或reflog访问。 输出结果如下所示:

    unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
    unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
    

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

    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 %pn' | sort
    

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

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

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

    git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
    git show de629830603289ef159268f443da79968360913a
    

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


    我只是做了一次git重置 - 很难并且失去了一次提交。 但是我知道提交散列,所以我能够做git cherry-pick COMMIT_HASH来恢复它。

    我在失去提交的几分钟内做了这个,所以它可能适用于你们中的一些人。


    感谢Mark Longair,我收回了我的东西!

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

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

    接下来我把它们都放在一个列表中,并将数据全部放在新文件中...你必须选择你的文件并重新命名它们,但是你只需要一些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
    
    链接地址: http://www.djcxy.com/p/63.html

    上一篇: hard with uncommitted files in the staging area

    下一篇: hard. Not found by fsck, not in reflog