Quiero tener un gancho Mercurial que se ejecutará antes de realizar una transacción que abortará la transacción si un archivo binario que se está confirmando es mayor que 1 megabyte. Encontré el siguiente código que funciona bien excepto por un problema. Si mi conjunto de cambios implica eliminar un archivo, este enlace generará una excepción.Gancho mercurial para no permitir archivos binarios grandes
El gancho (estoy usando 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
La excepción:
$ hg commit -m 'commit message'
error: pretxncommit hook raised an exception: apps/helpers/templatetags/[email protected]: not found in manifest
transaction abort!
rollback completed
abort: apps/helpers/templatetags/[email protected]: not found in manifest!
No estoy familiarizado con la escritura de ganchos Mercurial, así que estoy bastante confundido acerca de lo que es pasando. ¿Por qué le importa al gancho que se elimine un archivo si hg ya lo conoce? ¿Hay alguna manera de arreglar este gancho para que funcione todo el tiempo?
Actualización (resuelta): Modifiqué el gancho para filtrar los archivos que se eliminaron en el conjunto de cambios.
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
¿Cómo puedo filtrar los archivos eliminados de ctx.files()? – hekevintran
No importa, pude descifrarlo. Gracias. – hekevintran
capturar la excepción es suficiente;) – tonfa