2

我正在尝试添加到我们现有的预提交 SVN 挂钩,以便它检查并阻止特定目录中文件的文件大小增加。

我编写了一个 python 脚本来比较两个文件大小,它以两个文件作为参数并使用 sys.exit(0) 或 (1) 返回结果,这部分似乎工作正常。

我的问题是从批处理文件中调用 python 脚本,如何引用每个文件的新提交和以前的版本?现有代码对我来说是新的,还有一堆 %REPOS%、%TXN%s 等,我不知道如何使用它们。有没有一种简单、标准的方法来做到这一点?

它还已经包含使用 svnlook changed 循环通过已更改文件的代码,因此该部分不应该成为问题。

非常感谢

4

2 回答 2

5

如果您只需要比较文件大小,只需查看svnlook filesize命令即可。默认调用 - svnlook filesize repo path- 将为您提供 HEAD 修订版的大小path。要获取传入提交中路径的大小,请使用svnlook filesize repo path -t argv[2].

尽管如此,这里还是列出了版本化路径的所有修订的示例(传入的路径除外,因为这是预提交挂钩)。

#!/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编写整个脚本可能更容易。根据颠覆手册,预提交有三个输入;

  • 两个命令行参数
    • 存储库路径
    • 提交事务名称
  • 标准输入上的锁定令牌信息

如果你想知道哪些文件发生了变化,我建议你使用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 回答