2011-05-04 71 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