我怎样才能从意外的 git push -f 中恢复?

我怎样才能从意外的 git push -f 中恢复?

我只是git push -f错误地运行了,从而覆盖了远程分支。

原来的:

(remote origin:)
    branch master -> commit aaaaaaa
    branch foo    -> commit bbbbbbb

(local)
    branch master -> commit ccccccc
    branch foo    -> commit ddddddd

git push -f

(remote origin:)
    branch master -> commit ccccccc
    branch foo    -> commit ddddddd

在我的本地存储库中,我正在处理分支master,因此我可以将分支还原master为提交aaaaaaa,因为我可以aaaaaaa从中获取提交git reflog。但是,我无法获取提交,bbbbbbb因为我之前没有拉取git push -f

我已git reflog在远程存储库中尝试过,但裸存储库中的 reflog 中没有任何有用的东西。

我如何才能将分支恢复foobbbbbbb远程存储库中的提交状态?

(PS:我不知道的实际值bbbbbbb。)

答案1

HEAD 的 reflog 确实会没用,但是每个分支也有自己的 reflog;如果要恢复分支foo,请从git reflog foo(或git log -g foo) 开始。

即使没有 reflog,Git 仍然会将未使用的对象保留几天(几周?),因此您可以通过其他方式查找提交 ID 并手动将其重新附加到分支来进行恢复:

  1. 通过 SSH 连接到远程。

  2. 对远程存储库进行备份。

    tar -cvzf ~/project-backup.tgz /path/to/project.git
    
  3. 查找 的完整提交 ID bbbbbbb。只要您知道前几个字符,就可以使用git show bbbbbb和/或git log bbbbbb找出完整 ID。

    $ git show bbbbbbb
    commit bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    

    如果您根本不知道提交 ID,请运行git fsck,然后您应该会得到一个“悬而未决的提交”列表。使用git show <id>和检查每个提交,git log <id>直到找到正确的提交。

  4. 更新分支引用:

    git update-ref refs/heads/master aaaaaaaaaaaaaaa...
    git update-ref refs/heads/foo    bbbbbbbbbbbbbbb...
    

    手动方法(不太安全):

    echo aaaaaaaaaaaaaaa... > refs/heads/master
    echo bbbbbbbbbbbbbbb... > refs/heads/foo
    
  5. 检查git log mastergit log foo(仍在服务器上),以确保将正确的分支还原到正确的提交 ID。

答案2

其他服务可能也会提供此类服务。这可以节省一天的时间。

相关内容