2011-05-04 29 views
1

我有一个Subversion版本库,我想提取有关谁编辑什么,何时以及如何编辑历史的详细信息。我知道我可以运行svn log --xml来产生一个很好的易于使用的记录,说明每个修订版本中哪些路径被修改了。但我还想知道的是每个文件的编辑大小。如何从Subversion版本库提取“编辑大小”的日志

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

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

+0

为了什么目的,你想这样做? – khmarbaise 2011-05-04 12:23:02

+0

可能是像statsvn这样的工具可能适合你吗? – khmarbaise 2011-05-04 12:25:00

+0

我想开发一个可视化,以显示哪些用户是“大变动”用户,哪些用户是“轻触”用户。 statsvn是没有用的,因为它仅适用于“svn log”输出,并且我需要的数据比那里包含的更多。 – DamonJW 2011-05-04 12:52:21

回答

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) 
0

你可以使用这个什么:

svn blame -r10:10 URL/file.java 

这将打印输出已经在特定的变更,你可以用它来提取这些信息被改变,但这只是一个近似值不完全的线。

+0

感谢您的指针。但为了达到我的目的,我需要阅读svn日志,然后在每次更改任何文件时发出“svn blame”查询,这可能会导致很多存储库访问,并且可能相当缓慢。 – DamonJW 2011-05-04 12:50:56

相关问题