diff -u -r old/commit-access-control.cfg.example new/commit-access-control.cfg.example
--- old/commit-access-control.cfg.example	2005-06-15 12:09:15.946578600 -0500
+++ new/commit-access-control.cfg.example	2005-06-15 12:09:21.073799144 -0500
@@ -49,6 +49,22 @@
 #     usernames are specified in the section or if one of the listed
 #     usernames matches the author of the commit.
 #
+#  groups = groupname1 [groupname2] [groupname3 [groupname4 ...]]]
+#    or
+#  groups = groupname1 [groupname2]
+#  groups = groupname3 groupname4
+#
+#     This parameter is optional.  The group names listed here must be
+#     exact group names.  There is no regular expression matching for
+#     group names.  You may specify all the  group names that apply on one
+#     line or split the names up on multiple lines.  It is also allowable 
+#     to use numeric group ids.
+#
+#     The access rights from `access' are applied to ALL modified
+#     paths that match the `match' regular expression only if NO
+#     group names are specified in the section or if one of the listed
+#     group names matches the groups of the author of the commit.
+#
 # By default, because you're using commit-access-control.pl in the
 # first place to protect your repository, the script sets the
 # permissions to all files and directories in the repository to
@@ -72,3 +88,12 @@
 match  = ^(branches|tags|trunk)/project1/Makefile
 users  = joe
 access = read-only
+
+[Make the test path read-only by default]
+match  = ^test
+access = read-only
+
+[But open up commits to test to members of the QA group and the production group]
+match  = ^test
+groups = qa production
+access = read-write
diff -u -r old/commit-access-control.pl.in new/commit-access-control.pl.in
--- old/commit-access-control.pl.in	2005-06-15 12:09:15.946578600 -0500
+++ new/commit-access-control.pl.in	2005-06-15 12:09:21.073799144 -0500
@@ -38,6 +38,7 @@
 use strict;
 use Carp;
 use Config::IniFiles 2.27;
+use English;
 
 ######################################################################
 # Configuration section.
@@ -124,6 +125,7 @@
         {
           next if $param eq 'match';
           next if $param eq 'users';
+          next if $param eq 'groups';
           next if $param eq 'access';
           warn "$0: config file `$cfg_filename' section `$section' parameter ",
                "`$param' is being ignored.\n";
@@ -196,6 +198,15 @@
     die "$0: txn `$txn' has no author.\n";
   }
 
+
+# Get the author's groups from the OS
+my (@groups, %groups);
+@groups = map { $_ + 0 } split(' ', join(' ', $EGID, $GID));
+@groups{@groups} = (1) x @groups;
+@groups = sort keys %groups;
+#    %groups now has keys for every (numeric) group id, 
+#    while @groups contains the group (numeric) id list
+
 # Figure out what directories have changed using svnlook..
 my @dirs_changed = &read_from_process($svnlook, 'dirs-changed', $repos,
                                       '-t', $txn);
@@ -253,13 +264,13 @@
 foreach my $section (@sections)
   {
     # Decide if this section should be used.  It should be used if
-    # there are no users listed at all for this section, or if there
-    # are users listed and the author is one of them.
+    # there are no users or groups listed at all for this section, or if there
+    # are users listed and the author is one of them, or if there are groups
+    # listed and the author is a member of one of them.
     my $use_this_section;
 
     # If there are any users listed, then check if the author of this
-    # commit is listed in the list.  If not, then delete the section,
-    # because it won't apply.
+    # commit is listed in the list.  If not, then check for group membership.
     #
     # The configuration file can list users like this on multiple
     # lines:
@@ -270,6 +281,7 @@
     # any users at all with the scalar return from val() and if there,
     # then get the array value to get all users.
     my $users = $cfg->val($section, 'users');
+    my $groups = $cfg->val($section, 'groups');
     if (defined $users and length $users)
       {
         my $match_user = 0;
@@ -290,7 +302,41 @@
 
         $use_this_section = $match_user;
       }
-    else
+    # If there are any groups listed, then check if the author of this
+    # commit is a member of any listed in the list.  If not, then delete 
+    # the section,  because it won't apply.
+    #
+    # The configuration file can list groups like this on multiple
+    # lines:
+    #   groups = svn dev qa production
+    #   groups = source
+
+    # Because of the way Config::IniFiles works, check if there are
+    # any groups at all with the scalar return from val() and if there,
+    # then get the array value to get all groups.
+    elsif (defined $groups and length($groups))
+      {
+        my $match_group = 0;
+        foreach my $entry ($cfg->val($section, 'groups'))
+          {
+            unless ($match_group)
+              {
+                foreach my $group (split(' ', $entry))
+                  {
+                     # convert group names to numeric group ids
+                     $group = 0 + getgrnam($group) unless $group =~ /^\d+$/;
+                     if (exists($groups{$group}) and $groups{$group})
+                       {
+                         $match_group = 1;
+                         last;
+                       }
+                  }
+              }
+          }
+
+          $use_this_section = $match_group;
+      }
+    else 
       {
         $use_this_section = 1;
       }


