如何从subversion存储库中提取“编辑大小”的日志

时间:2011-05-04 12:11:08

标签: svn

我有一个Subversion存储库,我想提取有关谁编辑了什么,何时以及如何编辑的历史的详细信息。我知道我可以运行svn log --xml来生成一个易于使用的简单记录,记录每个修订版中哪些路径被更改。但我还想知道的是每个文件的编辑大小。

我知道有很多方法可以定义“编辑距离”,但我会对文本文件中的“不同行数”等任何简单的内容感到满意。

据推测,我可以通过解析svnadmin dump的输出来获得所有这些,但是我需要花时间学习转储文件格式,如果可以的话我宁愿避免这种格式。

2 个答案:

答案 0 :(得分:0)

您可以使用什么:

  svn blame -r10:10 URL/file.java

这将打印出在特定变更集中已更改的行,您可以使用这些行来提取此类信息,但这只是一个不完全近似的近似值。

答案 1 :(得分:0)

事实证明,svn转储格式很容易解析。如果我用svnadmin dump --deltas生成它,那么转储文件包含每个文件修改的增量,我可以合理地将增量的大小(以字节为单位)作为编辑距离。

如果有人来这里看,这是一个简单的Python脚本,它接受一个svn转储文件并打印出一个包含所有属性的XML文件。编辑大小包含在//path/Text-content-length条目中。

def read_defs(f):
    res = {}
    while True:
        l = f.readline()
        if l in ['','\n']: break
        s = l.split(': ',1)
        if len(s)!=2: assert False, 'Bad definition line '+l
        res[s[0]] = (s[1][:-1] if s[1].endswith('\n') else s[1])
    if len(res)==0 and l=='': return None
    return res

def read_props(f):
    res = {}
    lastkey = None
    while True:
        l = f.readline()
        if l.startswith('PROPS-END'): break
        ln = int(l.split()[1])
        l2 = f.read(ln); f.readline()
        if l.startswith('K'):
            lastkey = l2; res[l2] = None
        elif l.startswith('V'):
            res[lastkey] = l2
        else:
            assert False, 'Unexpected prop entry '+l
    return res

def parsedump(f):
        print '<?xml version="1.0"?>'
        print '<log>'
        inrevision,inpaths = False,False
        while True:
            d = read_defs(f)
            if d is None: break
            p = read_props(f) if 'Prop-content-length' in d else {}
            if 'Revision-number' in d:
                if inpaths: print '</paths>'; inpaths=False
                if inrevision: print '</logentry>'
                print '<logentry revision="'+d['Revision-number']+'">'
                inrevision = True
                for k,v in p.iteritems(): print '<'+k+'>'+v+'</'+k+'>'
            elif 'Node-path' in d:
                if not inpaths: print '<paths>'; inpaths=True
                print '<path>'
                for k,v in d.iteritems(): print '<'+k+'>'+v+'</'+k+'>'
                for k,v in p.iteritems(): print '<'+k+'>'+v+'</'+k+'>'
                print '</path>'
            cl = (int(d['Content-length']) if 'Content-length' in d else 0)
            pcl = (int(d['Prop-content-length']) if 'Prop-content-length' in d else 0)
            f.seek(cl-pcl,1)
        if inpaths: print '</paths>'
        if inrevision: print '</logentry>'
        print '</log>'

import sys
if __name__=='__main__':
    if len(sys.argv)==0:
        print 'Usage: svndump2xml FILENAME\nConverts FILENAME to xml, and prints to standard output'
        sys.exit(0)
    filename = sys.argv[1]
    with open(filename,'rb') as f:
        parsedump(f)