views:

310

answers:

5

I have a headstrong user who stubbornly insists on committing his binaries (executables, DLLs) into our subversion repositories. I'd go in and delete them, but of course nothing is ever really deleted from subversion.

While there are times when we need to commit binaries, I don't want users doing it as a matter of routine. I can set an ignore property but that doesn't prevent users from committing binaries if they are really determined. What I'd like to do is be able to control the ability to commit nominated file types, particularly .exe and .dll files, on a directory-by-directory basis.

Is there a way to do that in SVN? If it makes any differentce, we are using VisualSVN server and TortoiseSVN.

+3  A: 

Write a pre-commit hook that checks added files whether they fit your criteria.

You could use pre-commit-check.py as a starting point.

oefe
How would you suggest that I control this on a per-directory basis? Some directories I need to allow binaries to be checked in, others not. I would prefer not to have to hard-code this information into a script.
Tim Long
Your script could read the list of allowed paths from a file (you probably want to store the file on the server, not in the repository, so that the user cannot change it)If you want to store the information in the repository, you could use properties on the directory instead. This makes the information more local, and it will automatically handle new branches/tags.
oefe
+3  A: 

You can use a pre-commit hook. You'll have to write a simple program (in any language) which returns a non-zero value if the file is binary.

See here for generic documentation about repository hooks, and here for a python example from Apache.

You could look at the files names, or use file to look at their types.

Valentin Rocher
This -- in general you might also want to check against .dll, .exe, etc... filenames given this user's stubborn persistence.
Michael Greene
+1  A: 

You could use a pre-commit hook script that checks if the file is binary or textual.

tangens
+1  A: 

On TortoiseSVN you can have the user add .dll, .exe, etc to the ignore list. That way, they user won't accidentally check them in. See here for more info:

http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-ignore.html

On the server side, as others have stated, you can use a hook script.

Joel
Well, it's a headstrong user I'm dealing with here. He's been asked several times not to commit binaries but still does. I don't think it is a matter of remembering. That's why I need to _enforce_ the policy.
Tim Long
To be blunt, one way of enforcing this issue is to fire him. I don't mean this is your first method of handling it, but if push comes to shove, non-team players have no place on a team.
Lasse V. Karlsen
You can also deny any commit access. So he can only send his diffs as patches to his colleagues. This is the way Subversion itself restrict its write access to their repository: You have to prove that you write correct code by sending patches to the mailing list
Peter Parker
@Lasse - it's a volunteer effort, I can't really consider "firing" a volunteer who is doing good work. We do need his contribution to the project. I just need to stop him committing binaries. If this were not a voluntary effort and assuming I were the manager, then I'd be in a much stronger position, obviously.
Tim Long
The point is, he may not know not to check those in. He's just adding everything in the directory and committing. By having his Tortoise ignore them, the problem would likely go away.
Joel
+3  A: 

Here is a small hooks script which is doing what you want: You have to configure 2 things:

  • illegal_suffixes: a python list with all suffixes which should abort the commit
  • cmdSVNLOOK: the path to svnlook program

import sys
import subprocess 
import re

#this is a list of illegal suffixes:
illegal_suffixes = ['.exe','.dll']

# Path to svnlook command:
cmdSVNLOOK="/usr/bin/svnlook";

def isIllegalSuffix(progname):
    for suffix in illegal_suffixes:
        if (ptFilename.endswith(suffix)):
            return True
    return False

######### main program ################
repopath = sys.argv[1]
transact = sys.argv[2]

retVal = 0
svninfo = subprocess.Popen([cmdSVNLOOK, 'changed', '-t', transact, repopath], 
                                                        stdout = subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = svninfo.communicate();

prog = re.compile('(^[ACUDRM_])[ACUDRM]*\s+(.+)')  # regex for svnlook output
for line in stdout.split("\n"):
    if (line.strip()!=""):
        match=re.search(prog, line.strip())
        if match:
            mode = match.group(1) 
            ptFilename = match.group(2)
            if mode == 'A' and isIllegalSuffix(ptFilename): 
              retVal = 1
              sys.stderr.write("Please do not add the following ")
              sys.stderr.write("filetypes to repository:\n")
              sys.stderr.write(str(illegal_suffixes)+"\n")
              break
        else:
            sys.stderr.write("svnlook output parsing failed!\n")
            retVal = 1
            break
    else:
        # an empty line is fine!
        retVal = 0
sys.exit(retVal)
Peter Parker
Thanks, I appreciate you taking the time to post that - unfortunately we're using VisualSVN server which rund on Windows. I'll need either VBScript, JScript or a DOS batch file. Nevertheless, +1 for posting the script.
Tim Long
you can use python under windows, and svnlook is available with visual svn : https://www.visualsvn.com/support/svnbook/ref/svnlook/
Valentin Rocher
I developed this under windwos ;-) it is tested on linux and windows. You can surely use python for hooks and svnlook is part of VisualSVN, otherwise you can (and should) install the svn-commandline
Peter Parker
I've accepted this answer because the poster took the time to provide sample code. This didn't actually solve my problem because we're a Windows shop and running VisualSVN on Windows Server and we really are limited to VBScript (ugh!). Never theless, the logic is sound and I'm sure I can translate it.
Tim Long