[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Server-side file ignores

From: Simon Kennedy <simonk_at_looksoftware.com>
Date: 2005-03-07 00:07:25 CET

Peter Howe wrote:
Hi Peter,

I found that the 'svn:ignore' of limited use so I added our own property called 'look:accept'
(I work for a company called looksoftware) and then wrote a python script to reject any commits
that did not match the 'look:accept' property or one of the common predefined file extentions (*.c, *.cpp, etc).

I've attached a copy of the script to this email. I convert it to an exe with py2exe as I find deployment simpler.

Simon. K

> Hi All
> I know that there is the client-side "global-ignores" option which can be put into /etc/subversion/config in order to have SVN ignore certain files in users' working directories. However, I'd like to control this from the server (i.e. for all users, ensure that certain files are ignored - regardless of which client machine they are working on.)
> Is there a facility for this that I'm unaware of - and if so, is it possible to restrict it by directory? (e.g. under myrepos/src ignore .o but under myrepos/objs don't ignore .o). That's a contrived example by the way.
> Thanks in advance,
> Pete
> -----------------
> Peter Howe
> Icon Operations Manager, Asset Management
> Linedata Services (UK) Ltd. Bishopsgate Court 4-12 Norton Folgate London E1 6DB
> T +44 (0)20 7360 1901 F +44 (0)20 7360 1974 M +44 (0)7771 992 331
> E peter.howe@ldsam.com W www.ldsam.com
> MSN Messenger peter.howe@xenzero.com
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: users-help@subversion.tigris.org

# This script is intended to be used as hook script
# for the pre-commit event in subversion.
# The script verifies the types of files in the transaction have
# acceptable extensions like '.cpp' and '.h' and doesn't include binaries
# or other large files (as currently its very difficult to remove
# NOTE(sk): You can override the script by adding a wildcard pattern (e.g '*.wav')
# to a 'look:accept' property on the directory in which it resides
# (the patterns should be seperated by newlines)

# Import stuff!!
import os, sys, tempfile, re, win32evtlogutil, fnmatch

try :
    # NOTE(sk): the 'script' name is the first argument
    if not len(sys.argv) == 3 :
        # win32evtlogutil.ReportEvent("pre-commit", 1, 0, win32evtlog.EVENTLOG_ERROR_TYPE, ["Invalid arguments"], None, None)
        sys.exit("Invalid arguments")

    # NOTE(sk): Args popped off in reverse order
    # so the repospath is expected before the transaction id
    transaction = sys.argv.pop()
    repospath = sys.argv.pop()

    # NOTE(sk): Match 4 characters and the remainder is the filename
    status_re = re.compile("(.{4})(.+)")
    # NOTE(sk): Match a file with a specific file extention or a directory (ending with '/')
    ext_re = re.compile(".+?(\.(c|cpp|cxx|cc|tli|tlh|h|hpp|hxx|hh|inl|rc|resx|idl|asm|inc|dsp|dsw|sln|py|Pythonproj|vcproj|csproj|cs|htm|html|aspx|ascx|asax|asp|xml|css)$|/$)")

    # NOTE(sk): Define cache for directories and their 'look:accept' value
    accept_cache = {}

    # NOTE(sk): 'svnlook' command expected in global environment variables'
    svnpipe = os.popen("svnlook changed -t %s %s" % (transaction, repospath))
    contents = svnpipe.read()
    # contents = "A FunnyClogs/Test/New Wave Sound (5).wav\nA FunnyClogs/Test/New Microsoft Excel Worksheet (4).wav\n"

    # Process the output
    for line in contents.rstrip().split('\n') :
        m = status_re.match(line)
        if not m :
            # win32evtlogutil.ReportEvent("pre-commit", 1, 0, win32evtlog.EVENTLOG_ERROR_TYPE, ["Incorrect format: " + line], None, None)
            sys.exit("Incorrect format: " + line)
        attributes = m.group(1)
        filename = m.group(2)
        if attributes[0] == 'A' :
           if not filename[len(filename) - 1] == '/' :
                # the filename is a file, not a directory
                # split the filename into its file and parent components
                (parent, file) = os.path.split(filename)

                # their is no need to access the same property in the same directly
                # (and it will be a lot faster) so we cache the result so at most we only
                # have to look up the value of the property once per directory rather than once per file
                if parent not in accept_cache :
                    svnpipe = os.popen("svnlook propget -t %s %s look:accept \"%s\"" % (transaction, repospath, parent))
                    propvalue = svnpipe.read()
                    accept_cache[parent] = propvalue
                else :
                    propvalue = accept_cache[parent]
                found = None
                if len(propvalue) :
                    for value in propvalue.rstrip().split('\n') :
                        # perform a glob match (wildcard match) against the filename
                        if fnmatch.fnmatch(file, value) :
                            found = 1
                            # if one of the values match then we accept this file
                if not found and not ext_re.match(filename) :
                    # win32evtlogutil.ReportEvent("pre-commit", 1, 0, win32evtlog.EVENTLOG_ERROR_TYPE, ["Invalid extension: " + line], None, None)
                    sys.exit("Invalid extension: " + filename)
except SystemExit:
except Exception, e:
    # NOTE(sk): Only the 'SystemExit' exception seems to set the return
    # result correctly

To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org
Received on Mon Mar 7 00:09:52 2005

This is an archived mail posted to the Subversion Users mailing list.