好。我们都知道回购的每个克隆都可以作为克隆回购的备份。精细。此外,每个使用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/issue1
,refs/remote/notebook/master
等)。
如何使用此信息恢复notebook
上的回购?
答案 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
的本地参考。)