如何恢复远程崩溃的Git仓库?

时间:2013-09-25 08:05:56

标签: git restore git-remote

好。我们都知道回购的每个克隆都可以作为克隆回购的备份。精细。此外,每个使用git fetch更新其历史记录的远程帐户都会在已应用git fetch的仓库中备份。

但是当谈到备份的恢复时:我该怎么做? git fetch的正确命令是什么?

我的一个Git回购有问题:

git status
fatal: unable to read tree 0d2f806b01ded93e76a6f2c7a68429939f483026

是的,我可以start repairing the repo somehow,但是 - 幸运的是 - 我在git fetch notebook的回购邮件到期之前,在远程计算机上做了notebook

所以,我在desktop上有一个回购,其中包含我死亡回购的所有最新参考(如refs/remote/notebook/fix/issue1refs/remote/notebook/master等)。

如何使用此信息恢复notebook上的回购?

2 个答案:

答案 0 :(得分:2)

我找到了一个简单的方法:

desktop上,向git询问笔记本的已知远程分支:

git branch -r | grep notebook > notebookbranches

现在我们有一个名为notebookbranches的文件,它包含笔记本的所有分支。

notebook上,创建一个名为myrepo2

的新空回购广告
git init myrepo2

desktop上将此仓库添加为远程:

git remote add myrepo2 //notebook/D$/myrepo2 # working on Windows, use share name
git fetch myrepo2 # fetch current state of myrepo2

现在,在文件notebookbranches上打开您喜欢的编辑器。该文件目前看起来像这样:

notebook/fix/issue1
notebook/master
...

将文件修改为如下所示:

git push myrepo2 -f refs/remotes/notebook/fix/issue1
git push myrepo2 -f refs/remotes/notebook/master
...

使此文件可执行并执行它。

脚本完成后,所有分支都出现在myrepo2仓库中,但存储在.git/refs/remotes/notebook下。

获取此处的所有文件并将其移至.git/refs/heads/文件夹。

然后,你已经完成了。

答案 1 :(得分:1)

(1)在桌面上,将repo克隆到临时目录(您将在笔记本上按照您希望的方式设置所有分支标签)。让我们使用一个(裸)--mirror克隆来使它不容易被工作目录大惊小怪,并节省一些空间,同时还复制一个swell中的所有引用:

desktop$ mkdir /tmp/for_notebook; cd /tmp/for_notebook  # or similar
desktop$ git clone --mirror /path/to/repo

既然您已/tmp/for_notebook/repo.git--bare和/或--mirror倾向于添加.git),请将此克隆中的所有分支标签设置为与其所在位置相匹配笔记本:

desktop$ cd repo.git      # i.e., /tmp/for_notebook/repo.git
desktop$ for refname in   # ok, now see below

您可以在这里手动或通过脚本执行操作。如果有少量分支,您可以手动列出它们:

desktop$ for refname in fix/issue1 master; do
> git update-ref refs/heads/$refname refs/remotes/notebook/$refname
> done

如果有很多,您可以使用git for-each-ref自动执行此操作,但它会为您提供需要更多shell脚本的长(ish,可能只是使用完整)名称:

desktop$ for fullname in $(git for-each-ref \
> --format '%(refname)' refs/remotes/notebook/); do
> refname=${fullname#refs/remotes/notebook/}
> git update-ref refs/heads/$refname $fullname
> done

此时git branch应该只为您提供所需的分支,但如果有额外内容,您可以使用git branch -d删除它们。

(2)现在将其克隆到笔记本中,作为新的回购:

notebook$ git clone ssh://desktop.name//tmp/for_notebook/repo.git repo

毫无疑问,这已经建立了master分支;你只需要添加其他分支。重新更新master是无害的,因此,与以前相同的想法,除了遥控器现在是origin/*而不是for_notebook/*

notebook$ for fullname in $(git for-each-ref \
> --format '%(refname)' refs/remotes/origin/); do
> refname=${fullname#refs/remotes/origin/}
> git update-ref refs/heads/$refname $fullname
> done

您可能希望此时调整配置等,以便您没有desktop/tmp/for_notebook/repo.git作为origin。 (我通常只是直接编辑.git/config。)根据需要与笔记本的原始仓库.git/config进行比较。

(旧的reflog现在已经消失了,而且你保存了所有git stash个,因为那些都是未被复制到desktop的本地参考。)