【问题标题】:Mercurial hook to disallow committing large binary files禁止提交大型二进制文件的 Mercurial 钩子
【发布时间】:2010-03-31 09:24:10
【问题描述】:

我希望有一个 Mercurial 挂钩,该挂钩将在提交事务之前运行,如果提交的二进制文件大于 1 兆字节,它将中止事务。我发现以下代码可以正常工作,除了一个问题。如果我的变更集涉及删除文件,则此挂钩将引发异常。

钩子(我正在使用pretxncommit = python:checksize.newbinsize):

from mercurial import context, util
from mercurial.i18n import _
import mercurial.node as dpynode

'''hooks to forbid adding binary file over a given size

Ensure the PYTHONPATH is pointing where hg_checksize.py is and setup your
repo .hg/hgrc like this:

[hooks]
pretxncommit = python:checksize.newbinsize
pretxnchangegroup = python:checksize.newbinsize
preoutgoing = python:checksize.nopull

[limits]
maxnewbinsize = 10240
'''

def newbinsize(ui, repo, node=None, **kwargs):
    '''forbid to add binary files over a given size'''
    forbid = False
    # default limit is 10 MB
    limit = int(ui.config('limits', 'maxnewbinsize', 10000000))
    tip = context.changectx(repo, 'tip').rev()
    ctx = context.changectx(repo, node)
    for rev in range(ctx.rev(), tip+1):
        ctx = context.changectx(repo, rev)
        print ctx.files()
        for f in ctx.files():
            fctx = ctx.filectx(f)
            filecontent = fctx.data()
            # check only for new files
            if not fctx.parents():
                if len(filecontent) > limit and util.binary(filecontent):
                    msg = 'new binary file %s of %s is too large: %ld > %ld\n'
                    hname = dpynode.short(ctx.node())
                    ui.write(_(msg) % (f, hname, len(filecontent), limit))
                    forbid = True
    return forbid

例外:

$  hg commit -m 'commit message'
error: pretxncommit hook raised an exception: apps/helpers/templatetags/include_extends.py@bced6272d8f4: not found in manifest
transaction abort!
rollback completed
abort: apps/helpers/templatetags/include_extends.py@bced6272d8f4: not found in manifest!

我不熟悉编写 Mercurial 钩子,所以我对发生的事情感到很困惑。如果 hg 已经知道文件被删除,为什么钩子会关心它?有没有办法修复这个钩子,让它一直工作?

更新(已解决): 我修改了钩子以过滤掉在变更集中删除的文件。

def newbinsize(ui, repo, node=None, **kwargs):
    '''forbid to add binary files over a given size'''
    forbid = False
    # default limit is 10 MB
    limit = int(ui.config('limits', 'maxnewbinsize', 10000000))
    ctx = repo[node]
    for rev in xrange(ctx.rev(), len(repo)):
        ctx = context.changectx(repo, rev)

        # do not check the size of files that have been removed
        # files that have been removed do not have filecontexts
        # to test for whether a file was removed, test for the existence of a filecontext
        filecontexts = list(ctx)
        def file_was_removed(f):
            """Returns True if the file was removed"""
            if f not in filecontexts:
                return True
            else:
                return False

        for f in itertools.ifilterfalse(file_was_removed, ctx.files()):
            fctx = ctx.filectx(f)
            filecontent = fctx.data()
            # check only for new files
            if not fctx.parents():
                if len(filecontent) > limit and util.binary(filecontent):
                    msg = 'new binary file %s of %s is too large: %ld > %ld\n'
                    hname = dpynode.short(ctx.node())
                    ui.write(_(msg) % (f, hname, len(filecontent), limit))
                    forbid = True
    return forbid

【问题讨论】:

    标签: mercurial hook pre-commit-hook mercurial-hook


    【解决方案1】:

    这在最近的 Mercurial 中的 shell 钩子中很容易做到:

    if hg locate -r tip "set:(added() or modified()) and binary() and size('>100k')"; then
      echo "bad files!"
      exit 1
    else
      exit 0
    fi
    

    这里发生了什么?首先,我们有一个文件集来查找所有有问题的已更改文件(参见 hg 1.9 中的“hg 帮助文件集”)。 'locate' 命令类似于状态,只是它只列出文件并在找到任何内容时返回 0。我们指定 '-r tip' 来查看待提交的提交。

    【讨论】:

      【解决方案2】:

      for f in ctx.files() 将包含已删除的文件,您需要将其过滤掉。

      (您可以将for rev in range(ctx.rev(), tip+1): 替换为for rev in xrange(ctx.rev(), len(repo)):,并删除tip = ...

      如果您使用的是现代 hg,则不要使用 ctx = context.changectx(repo, node),而是使用 ctx = repo[node]

      【讨论】:

      • 如何从 ctx.files() 中过滤掉删除的文件?
      • 捕获异常就足够了;)
      猜你喜欢
      • 2013-10-14
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 2012-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多