Parasu
Parasu

Reputation: 192

SVN: Issue with commit-access-control.cfg

I am new to SVN and trying to learn it. I have setup the SVN server and I am able to check-in/check-out

files from it. As a next step, I am trying to do access control on it and also trying to add some commit hooks to

prevent some unwanted check-ins.

Here are my svn repositories:

/svnrepos/repo1
/svnrepos/repo2
/svnrepos/test    >>>>>>> My test repository for playing around with SVN

Now I am trying to do the following using pre-commit:

1. Preventing some users to check-in to a directory or any of its sub-folders
2. Preventing some files (say .class files) to be checked in by all users

Here is my environment:

Perl: v5.14.2 (linux 32-bit )
SVN: 1.7.4  (r1295709)
OS: Linux svnserver 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:54 EDT 2009 i686 i686 i386 GNU/Linux

I am running the svn server using the command "svnserve -d -r /svnrepos --log-file /var/log/svn.log"

Now I am trying to provide access restrictions to the repository /svnrepos/test. I am trying to edit the commit-access-control.cfg file to provide the access restriction. Here are the contents of this config file:

[Make everything read-only for all users]
match   = .*
access  = read-only

[Make test project read-write for admin users ]
match  = ^trunk/svnrepos/test/samplefile.txt
users  = PR111319
access = read-write

The following match patterns does not seem to work:

match=^trunk/svnrepos/test/samplefile.txt
match=^/svnrepos/test/samplefile.txt
match=/svnrepos/test/samplefile.txt
match=/test/samplefile.txt
match=^/samplefile.txt

Whatever match pattern I give, I get the following error while commiting the file samplefile.txt:

org.apache.subversion.javahl.ClientException: A repository hook failed
svn: Commit failed (details follow):
svn: Commit blocked by pre-commit hook (exit code 1) with output:
/svnrepos/test/hooks/commit-access-control.pl: user `PR111319' does not have permission to commit to 

these paths:
  /
  samplefile.txt

However if I give the match as .* then I am able to successfully commit it. From this, I am quite clear that the problem lies with 'match'

Here are the contents of the pre-commit file:

68 REPOS="$1"
69 TXN="$2"
70
71 # Make sure that the log message contains some text.
72 SVNLOOK=/opt/CollabNet_Subversion/bin/svnlook
73 $SVNLOOK log -t "$TXN" "$REPOS" | \
74    grep "[a-zA-Z0-9]" > /dev/null || exit 1
75
76 # Check that the author of this commit has the rights to perform
77 # the commit on the files and directories being modified.
78 /opt/ActivePerl-5.14/bin/perl "$REPOS/hooks/commit-access-control.pl" "$REPOS" "$TXN" "$REPOS/hooks/commit-access-control.cfg" || exit 1
79
80 # All checks passed, so allow the commit.
81 exit 0

Please let me know if you need any more info.

Thanks and Regards, Parasuraman.R

Upvotes: 2

Views: 4052

Answers (1)

David W.
David W.

Reputation: 107080

First thing first:

  • You only have a single Subversion repository.

I just want to make this clear. All of your repositories will be under the same hook. So, no one can commit to repos1 or repos2 unless your hook permits them.

Try using the svnlook command since that's what the hook script is using. This will give you a better clue on how to specify your files in your pre-commit hook's configuration file:

$ svnlook changed -r $revision $repository_directory

The $repository_directory is the directory that contains the repository when you did the svnadmin create command. You'll need to give it either the relative path or the full path. The $revision is the revision number of the Subversion revision you're looking at. Try a few different revisions to see what's being changed You can get the last revision via this command:

$ svnlook youngest $repository_directory

What you will notice is that there is no / at the front of the file's name and that the full path is being specified.


I would like to make a few recommendations:

  • Since you're new to Subversion, forget the pre-commit hook for now. Try using Subversion for a while sans hooks and get an idea how it flows.

  • You have trunk being specified in your hook, but I don't see truck in your repository. I have a feeling you don't quite get the concept of how the standard Subversion repository structure works.

The default use of Subversion is to have three directories called trunk, tags, and branches (yes, these are directory names), in the root of your repository. In your case, you probably want the following directories since you're treating your single repository as three separate ones:

  • repos1/trunk
  • repos1/tags
  • repos1/branches
  • repos2/trunk
  • repos2/tags
  • repos2/branches
  • test/trunk
  • test/tags
  • test/branches

You create your repository, then before any of your developers can get their grubby little paws on the repository, you create these nine directories. All files in your repository will then be placed under one of these nine directories.

Again, there's no reason why this must be done. If you never branch or tag your code, you really don't have to do this. The directories don't even have to be named trunk, branches, and tags. They could be named main, branches, labels or moe, larry, curly for all Subversion cares.

However, everybody else uses trunk, branches, and tags, and since I'm the type of person who'd jump off the roof if everyone else did, I recommend you too follow the standard naming convention too.

Most development takes place under the trunk directory for that repository. If you need to create a branch, you can copy the files under trunk to the branches directory with a particular branch name. For example, I need to create a bug fix branch for release 1.3:

$ svn cp svn://localhost/repos1/trunk svn://localhost/repos1/branches/1.3-bug-fixes

To tag a file when you do a release, simply copy the directory where you did your work under the tags directory:

$ svn cp svn://localhost/repos1/trunk svn://localhost/repos1/tags/1.3
$ svn cp svn://localhost/repos1/branches/1.3-bug-fixes svn://localhost/repos1/tags/1.3.1

That's how Subversion does tagging and branching. It's different from most version control systems out there, but it has a lot of nice advantages (It's simple, it's easy to find the names of labels and branches via the svn ls command, and it gives you a complete history of your branches and tags.)

  • Once you get a better understanding how Subversion works and how the repository works, you can then try creating a pre-commit hook. I humbly recommend that you use my pre-commit hook. Unlike the one you're using, it's being actively maintained and is well documented. Plus, it has a lot of nifty features.

Upvotes: 1

Related Questions