2

我是 SVN 的新手,正在努力学习它。我已经设置了 SVN 服务器,我可以签入/签出

来自它的文件。作为下一步,我正在尝试对其进行访问控制,并尝试添加一些提交挂钩

防止一些不需要的签到。

这是我的 svn 存储库:

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

现在我正在尝试使用预提交执行以下操作:

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

这是我的环境:

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

我正在使用命令“svnserve -d -r /svnrepos --log-file /var/log/svn.log”运行 svn 服务器

现在我正在尝试为存储库/svnrepos/test 提供访问限制。我正在尝试编辑 commit-access-control.cfg 文件以提供访问限制。以下是此配置文件的内容:

[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

以下匹配模式似乎不起作用:

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

无论我给出什么匹配模式,在提交文件 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

但是,如果我将匹配项指定为 .* ,那么我就可以成功提交它。由此,我很清楚问题出在“匹配”上

以下是预提交文件的内容:

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

如果您需要更多信息,请告诉我。

谢谢和问候, Parasuraman.R

4

1 回答 1

1

第一件事:

  • 您只有一个 Subversion 存储库。

我只想说清楚。您的所有存储库都将在同一个钩子下。因此,除非您的钩子允许,否则repos1没有人可以承诺。repos2

尝试使用该svnlook命令,因为这是钩子脚本正在使用的。这将为您提供有关如何在预提交挂钩的配置文件中指定文件的更好线索:

$ svnlook changed -r $revision $repository_directory

是执行命令$repository_directory时包含存储库的目录。svnadmin create您需要为其提供相对路径或完整路径。这$revision是您正在查看的 Subversion 修订版的修订版号。尝试几个不同的版本,看看有什么改变你可以通过这个命令获得最新的版本:

$ svnlook youngest $repository_directory

您会注意到/文件名的前面没有,并且指定了完整路径。


我想提出几点建议:

  • 由于您是 Subversion 的新手,所以暂时忘记pre-commit钩子。尝试在没有钩子的情况下使用 Subversion 一段时间,并了解它是如何流动的。

  • 您已trunk在您的钩子中指定,但我没有truck在您的存储库中看到。我感觉您不太了解标准 Subversion 存储库结构的工作原理。

Subversion 的默认用法是在存储库trunk的根目录中拥有三个名为、tagsbranches的目录(是的,这些是目录名称)。在您的情况下,您可能需要以下目录,因为您将单个存储库视为三个独立的存储库:

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

您创建了存储库,然后在您的任何开发人员可以在存储库上获得他们肮脏的小爪子之前,您创建了这九个目录。然后将存储库中的所有文件放在这九个目录之一下。

同样,没有理由必须这样做。如果你从不分支或标记你的代码,你真的不必这样做。目录甚至不必命名为trunk,branchestags. 它们可以被命名为main, branches,labelsmoe, larry,curly用于所有 Subversion 关心。

但是,其他人都使用trunk,branchestags, 并且由于我是那种如果其他人都这样做的话会从屋顶跳下来的人,我建议你也遵循标准命名约定。

大多数开发都在该存储库trunk的目录下进行。如果您需要创建一个分支,您可以将下面的文件复制到具有特定分支名称的目录中。例如,我需要为 1.3 版创建一个错误修复分支:trunkbranches

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

要在发布时标记文件,只需在目录下复制您所做工作的tags目录:

$ 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

这就是 Subversion 进行标记和分支的方式。它与大多数版本控制系统不同,但它有很多不错的优势(它很简单,很容易通过svn ls命令找到标签和分支的名称,它为您提供了分支和标签的完整历史记录。)

  • 一旦你更好地理解了 Subversion 是如何工作的以及存储库是如何工作的,你就可以尝试创建一个 pre-commit 钩子。我谦虚地建议你使用我的pre-commit hook。与您正在使用的不同,它正在积极维护并且有据可查。此外,它还有很多漂亮的功能。
于 2012-06-11T14:25:18.630 回答