Limit the size of Subversion commitment

Has your subversion repository ever been abused by massive commitments?
If not, I should say that you are lucky. Never mind that someday you might be abused as it’s hard to predict what the non-Ops are working on and trying to do.
It would suck just because some people were committing large files without any legitimate reasons. There are other annoying consequences. Your daily backup would take longer time to finish eating more disk space, and your commitment analysis tool would get hiccups like ours.

So, How can we limit the size of a Subversion commitment?
The solution is quite easy, use the pre-commit hook. You can find some examples after searching around. Here’s the script that I use. It reads the tmp files in db/transactions/, caculate the total size and compare it with your settings (db/tranactions only saves changesets, not original files).

If the size exceeds your limit, the commitment fails and user will be warned with details.

#!/usr/bin/env python
#
# Limit the size of SVN commits. It reads db/transactions to caculate commit size.
# Put the follwoing 3 lines in hook/pre-commit hook like this:
#
# REPOS="$1"
# TXN="$2"
# check_commit_size.py "$REPOS" "$TXN" || exit 1
#

import sys,os,popen2

# The size is not an exact value.
MAX_BYTES = 10000000

def printUsage():
    sys.stderr.write('Usage: %s "$REPOS" "$TXN" ' % sys.argv[0])

def getTransactionSize(repos, txn):
    txnRevPath = repos+'/db/transactions'+'/'+txn+'.txn'+'/rev'
    return os.stat(txnRevPath)[6]

def checkTransactionSize(repos, txn):
    size = getTransactionSize(repos, txn)
    if (size > MAX_BYTES):
        sys.stderr.write("Sorry, you are trying to commit %d bytes, which is larger than the limit of %d.\n" % (size, MAX_BYTES))
        sys.stderr.write("If you think you have a good reason to, email to Ops and ask for permission.")
        sys.exit(1)

if __name__ == "__main__":
    #Check that we got a repos and transaction with this script
    if len(sys.argv) != 3:
        printUsage()
        sys.exit(2)
    else:
        repos = sys.argv[1]
        txn = sys.argv[2]

    checkTransactionSize(repos, txn)
Share Button

Leave a comment

Your email address will not be published. Required fields are marked *