0

好的。我们都知道,每个 repo 的克隆都可以作为克隆 repo 的备份。美好的。此外,每个更新历史记录的遥控器git fetch都备份在git fetch应用的存储库中。

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

我的一个 Git 存储库有问题:

git status
fatal: unable to read tree 0d2f806b01ded93e76a6f2c7a68429939f483026

是的,我可以以某种方式开始修复 repo,但是 - 幸运的是 -在我的 repo死亡git fetch notebook之前,我在远程机器上做了一个。notebook

所以,我有一个关于 的回购desktop,在那里我有我死去的回购的所有最新参考(如refs/remote/notebook/fix/issue1refs/remote/notebook/master等)。

如何notebook使用此信息恢复 repo?

4

2 回答 2

2

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

on desktop,向 git 询问 notebook 的已知远程分支:

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

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

脚本完成后,所有分支都存在于myrepo2repo 中,但存储在.git/refs/remotes/notebook.

获取此处存在的所有文件并将它们移动到.git/refs/heads/文件夹中。

然后,你就完成了。

于 2013-09-25T09:02:29.483 回答
1

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

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

此时您可能想要调整配置等,以便您没有desktopand /tmp/for_notebook/repo.gitas origin。(我通常通过直接编辑来做到这一点.git/config。)根据需要与笔记本的原始存储库进行比较.git/config

(旧的 reflog 现在已经消失了,git stash你保存的所有 es 都没有了,因为这些都是没有被复制到的本地 refs desktop。)

于 2013-09-25T08:53:06.543 回答