修改svn历史数据

svn用久了后,会越来越庞大,客户端的.svn目录也会越来越大,特别是有人喜欢把音频、视频、自动生成的工程文件提交到svn里,这就带来了svn历史数据的清理需求,可能你只想保留最近几百个版本,或者是想干掉当初失误提交的二进制文件。

尝试直接去修改服务端的数据文件不太现实,文件很多,外加各种摘要验签。这个时候可以使用svnadmin的导出导入功能。

导出:


./bin/svnadmin dump -r1:1000 data > res.dump

创建一个空的数据目录:


./bin/svnadmin create new_data

导入:


./bin/svnadmin load new_data < res.dump

其实导出的dump文件很像一个http的抓包文件,均为开头为属性信息(类似http的header),接着是数据文件内容(类似http的body)。

不过因为dump文件含有二进制,所以不方便手动直接编辑,就需要脚本来处理。写了个简单的脚本,用于修改dump文件,代码如下:


key = 'Node-path: origin.bin'
val = open('replace.bin').read()

with open('./res.dump') as f:
    data = f.read()

beg_pos = data.find(key)
end_pos = data.find('PROPS-END', beg_pos)

from cStringIO import StringIO
from hashlib import sha1, md5
props = StringIO(data[beg_pos : end_pos])
meta = {}
for i in props:
    if ': ' in i:
        a, b = i.split(': ')
        meta[a.strip()] = b.strip()

content_len = int(meta['Text-content-length'])
prop_len = int(meta['Prop-content-length'])
meta['Text-content-length'] = len(val)
meta['Text-content-sha1'] = sha1(val).hexdigest()
meta['Text-content-md5'] = md5(val).hexdigest()
meta['Content-length'] = meta['Text-content-length'] + int(meta['Prop-content-length'])

fields = ('Node-path', 'Node-kind', 'Node-action', 'Prop-content-length', 'Text-content-length', 'Text-content-md5', 'Text-content-sha1', 'Content-length')
fields_text = '\n'.join('%s: %s' % (i, meta[i]) for i in fields)

res = data[:beg_pos] + fields_text + "\n\n" + data[end_pos+10-prop_len:end_pos] + "PROPS-END\n" + val + data[end_pos+10+content_len:]
with open('modify.dump', 'w') as f:
    f.write(res)

如果因为服务端改了数据,客户端出现svn: E155017: Checksum mismatch for错误,可使用如下方式解决:


svn update --set-depth empty
svn update --set-depth infinity

 

发表于 2018年09月21日 20:16   评论:0   阅读:2129  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo