2010-03-31 12 views
10

मैं एक मर्क्यूरियल हुक चाहता हूं जो एक लेनदेन करने से पहले चलाएगा जो लेन-देन को रोक देगा यदि एक बाइनरी फ़ाइल 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/[email protected]: not found in manifest 
transaction abort! 
rollback completed 
abort: apps/helpers/templatetags/[email protected]: not found in manifest! 

मैं मर्क्युरियल हुक लेखन से परिचित नहीं हूँ, इसलिए मैं बहुत क्या लेकर संदेह में हूँ चल रहा। हुक देखभाल क्यों करता है कि फ़ाइल को हटा दिया गया है अगर एचजी पहले से ही इसके बारे में जानता है? क्या इस हुक को ठीक करने का कोई तरीका है ताकि यह हर समय काम करे?

अद्यतन (हल): मैंने परिवर्तन में हटाए गए फ़ाइलों को फ़िल्टर करने के लिए हुक को संशोधित किया।

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 

उत्तर

4

for f in ctx.files() शामिल होंगे निकाली गई फ़ाइलें, तो आप उन को फिल्टर करने की जरूरत है।

(और आप for rev in xrange(ctx.rev(), len(repo)): द्वारा for rev in range(ctx.rev(), tip+1): की जगह ले सकता है, और tip = ... निकालने के लिए) आप एक आधुनिक एचजी उपयोग कर रहे हैं

, आप ऐसा नहीं करते हैं ctx = context.changectx(repo, node) लेकिन ctx = repo[node] बजाय।

+0

मैं हटाए गए फ़ाइलों को ctx.files() से कैसे फ़िल्टर करूं? – hekevintran

+0

कोई बात नहीं, मैं इसे समझने में सक्षम था। धन्यवाद। – hekevintran

+0

अपवाद को पकड़ना पर्याप्त है;) – tonfa

5

यह हाल मर्क्युरियल में वास्तव में एक खोल हुक में क्या करना आसान है:

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

यहाँ क्या हो रहा है? सबसे पहले हमारे पास समस्याग्रस्त सभी बदली गई फ़ाइलों को खोजने के लिए एक फाइलसेट है (एचजी 1.9 में 'एचजी सहायता फाइलसेट' देखें)। 'ढूँढें' कमांड स्थिति की तरह है, सिवाय इसके कि यह केवल फाइलों को सूचीबद्ध करता है और अगर उसे कुछ मिलता है तो 0 देता है। और हम लंबित प्रतिबद्धता को देखने के लिए '-r tip' निर्दिष्ट करते हैं।