恢复corrupted git-svn repository的过程记录
问题
由于主机异常宕机导致git中的文件变成了0字节的,执行git相关的命令报错。
fatal: object 016660b7605cfc2da85f631bbe809f7cb7962608 is corrupted
恢复过程
# 从镜像clone中恢复一个git repo,幸好有一个mirror clone。
git clone --mirror billing@10.164.129.25:/billing/git/cmcc.git /srv/git/cmcc1.git
# 把损坏的git repo中与SVN相关的内容复制到新的git repo中。
cp -R cmcc.bad.git/config cmcc1.git/
cp -R cmcc.bad.git/svn cmcc1.git/
cp -R cmcc.bad.git/logs cmcc1.git/
...
cp -R cmcc.bad.git/info/refs cmcc1.git/info/
cp -R cmcc.bad.git/refs/heads/master cmcc1.git/refs/heads/
# 根据git log中的信息对新git repo中的相关文件中的hash做了些调整
# 尝试执行/usr/bin/git --git-dir=/srv/git/cmcc1.git svn fetch 仍然报错
唯一没法调整的文件是svn/refs/heads/master/.rev_map.21a24a4a-c245-7e45-a0a4-218b2805dfce,这个不是文本的。
幸运的是从网上搜到了一个生成rev_map文件的脚本 https://gist.github.com/1953425
1: #! /usr/bin/env gawk -f
2: # git --no-pager log | gawk -f this-script > revmap.txt
3: # xxd -c 24 -r revmap.txt \
4: # .git/svn/refs/remotes/trunk/.rev_map.cfe28804-0f27-0410-a406-dd0f0b0b656f
5: # 0000000: 0000 0001 cce6 285e 48e1 e3cc 0d7d 0617 beb0 4e88 a126 8634
6: # 0000018: 0000 0006 6e4f ada4 bed4 6660 c987 dc74 1243 8973 16cc c810
7: BEGIN {
8: FS=" "
9: # this number comes from ``git --no-pager log | grep ^commit | wc -l``
10: # and is ZERO-indexed because the last xxd will begin with 0000
11: # you might be tempted to think it is the highest r-number, but no,
12: # because evidently not every subversion commit made it to git
13: cnt=30554
14: }
15: /^commit / {
16: cmit=$2
17: }
18: /git-svn/ {
19: # remove everything except the r-number
20: sub(/[^@]+@/,"")
21: # remove the repository-id
22: sub(/ .*$/,"")
23: addr=cnt * 24
24: # thankfully, xxd is tolerant of not having
25: # any spaces, so we can just dump the commitish
26: # right into the file
27: printf "%08x: %08x%s \n", addr, $0, cmit
28: cnt = cnt - 1
29: }
删除现有的rev_map文件,按照上面的说明重新生成了一个。
执行 /usr/bin/git --git-dir=/srv/git/cmcc1.git svn fetch 成功。
操作过程经过很多失败的尝试,记录不是很完整,仅作参考。