2

既存のpre-commitSVNフックに追加して、特定のディレクトリ内のファイルのファイルサイズの増加をチェックしてブロックするようにしています。

2つのファイルサイズを比較するPythonスクリプトを作成しました。これは、引数として2つのファイルを受け取り、sys.exit(0)または(1)を使用して結果を返します。この部分は正常に機能しているようです。

私の問題は、バッチファイルからPythonスクリプトを呼び出すことです。各ファイルの新しくコミットされたバージョンと以前のバージョンを参照するにはどうすればよいですか?既存のコードは私にとって新しいものであり、%REPOS%、%TXN%sなどが混乱しているため、それらの使用方法がわかりません。これを行うための簡単で標準的な方法はありますか?

また、変更されたsvnlookを使用して変更されたファイルをループするコードもすでに含まれているため、一部が問題になることはありません。

どうもありがとう

4

2 に答える 2

5

ファイルサイズを比較するだけでよい場合は、svnlook filesizeコマンドを探すだけです。デフォルトの呼び出し---svnlook filesize repo pathは、のHEADリビジョンのサイズを示しますpath。着信コミットのパスのサイズを取得するには、を使用しますsvnlook filesize repo path -t argv[2]

それでも、バージョン管理されたパスのすべてのリビジョンを一覧表示する例を次に示します(これはpre-commitフックであるため、着信パスを除く)。

#!/usr/bin/env python

from sys import argv, stderr, exit
from subprocess import check_output

repo = argv[1]
transaction = argv[2]

def path_history(path, limit=5):
    path = '/%s' % path
    cmd = ('svnlook', 'history', '-l', str(limit), repo, path)
    out = check_output(cmd).splitlines()[2:]

    for rev, _path in (i.split() for i in out):
        if _path == path:
            yield rev

def commit_changes():
    cmd = ('svnlook', 'changed', repo, '-t', transaction)
    out = check_output(cmd).splitlines()

    for line in out:
        yield line.split()

def filesize(path, rev=None, trans=None):
    cmd = ['svnlook', 'filesize', repo, path]
    if rev:     cmd.extend(('-r', str(rev)))
    elif trans: cmd.extend(('-t', str(trans)))

    out = check_output(cmd)
    return out.rstrip()

def filesize_catwc(path, rev=None, trans=None):
    '''A `svnlook filesize` substitute for older versions of svn. 
    Uses `svnlook cat ... | wc -c` and should be very inefficient
    for large files.'''

    arg = '-r %s' % rev if rev else '-t %s' % trans
    cmd = 'svnlook cat %s %s %s | wc -c' % (arg, repo, path)

    out = check_output(cmd, shell=True)
    return out.rstrip()


for status, path in commit_changes():
    if status in ('A', 'M', 'U'):
        # get the last 5 revisions of the added/modified path
        revisions = list(path_history(path))
        headrev = revisions[0]

        oldsize = filesize(path, rev=headrev)
        newsize = filesize(path, trans=transaction)
于 2012-09-24T20:03:32.557 に答える
1

pre-commitスクリプト全体をPythonで作成する方がおそらく簡単です。Subversionハンドブックによると、事前コミットするための3つの入力があります。

  • 2つのコマンドライン引数
    • リポジトリパス
    • トランザクション名をコミットする
  • 標準入力のロックトークン情報

どのファイルが変更されたかを知りたい場合は、subprocess.check_output()関数を使用してを呼び出すことをお勧めしますsvnlook changed。内容が変更されたファイルについては、を呼び出しsvnlook filesizeて、リポジトリ内の最後のリビジョンのファイルのサイズを取得する必要があります。os.stat()関数に示されているように、クエリを実行する必要がある作業ディレクトリ内の同等のファイルのサイズgetsizes()

import subprocess
import sys
import os

repo = sys.argv[1]
commit_name = sys.argv[2]

def getsizes(rname, rfile):
   '''Get the size of the file in rfile from the repository rname. 
   Derive the filename in the working directory from rfile, and use 
   os.stat to get the filesize. Return the two sizes.
   '''
   localname = rfile[10:].strip() # 'U   trunk/foo/bar.txt' -> 'foo/bar.txt'
   reposize = subprocess.check_output(['svnlook', 'filesize', rname, rfile])
   reposize = int(reposize)
   statinfo = os.stat(localname)
   return (reposize, statinfo.st_size)

lines = subprocess.check_output(['svnlook', 'changed', repo]).splitlines()
for line in lines:
    if line.startswith('U ') or line.startswith('UU'):
       # file contents have changed
       reposize, wdsize = getsizes(repo, line)
       # do something with the sizes here...
    elif line.startswith('_U'):
       # properties have changed
       pass
于 2012-09-24T20:04:46.800 に答える