Frage

Ich möchte ein Mercurial Haken haben, bevor sie sich eine Transaktion ausgeführt wird, dass die Transaktion abbrechen, wenn eine Binärdatei begangen größer als 1 Megabyte ist. Ich fand den folgenden Code, der in Ordnung, außer für ein Problem funktioniert. Wenn meine changeset Entfernen einer Datei beinhaltet, wird dieser Haken eine Ausnahme aus.

Der Haken (Ich verwende 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

Die Ausnahme:

$  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!

Ich bin nicht vertraut mit Mercurial Haken zu schreiben, so dass ich über ziemlich bin verwirrt, was los ist. Warum der Haken darauf, dass eine Datei entfernt wurde, wenn hg schon bekannt? Gibt es eine Möglichkeit, diese Haken zu befestigen, so dass es die ganze Zeit funktioniert?

Update (gelöst): Ich änderte den Haken ausfiltern Dateien, die in der changeset entfernt wurden.

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
War es hilfreich?

Lösung

for f in ctx.files() entfernte Dateien enthalten wird, müssen Sie diejenigen heraus filtern.

(und Sie können for rev in range(ctx.rev(), tip+1): durch for rev in xrange(ctx.rev(), len(repo)): ersetzen und entfernen tip = ...)

Wenn Sie einen modernen hg verwenden, Sie nicht tun ctx = context.changectx(repo, node) aber ctx = repo[node] statt.

Andere Tipps

Das ist wirklich einfach in einem Shell-Haken in der letzten Mercurial zu tun:

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

Was ist hier los? Zuerst haben wir eine fileset alle geänderten Dateien zu finden, die problematisch sind (siehe ‚hg Hilfe Dateigruppen‘ in hg 1.9). Der ‚lokalisiert‘ Befehl ist wie Status, außer es nur Listen von Dateien und gibt 0 zurück, wenn es etwas findet. Und wir geben ‚-r Spitze‘ zu Blick auf die anstehenden begehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top