[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: pre-revprop-change Script

From: David Weintraub <qazwart_at_gmail.com>
Date: Sun, 26 Jul 2009 20:05:58 -0400

Just a friendly recommendation: If you're going to administer Subversion,
you need to read the Subversion manual. This manual is available at
http://svnbook.com. Fortunately, the manual is extremely well written and
shouldn't take you that long to go through it. Subversion is very simple to
administer and use compared to a lot of revision control systems, and it's
one of the reasons why so many developers like it so much.

To answer your questions:

Under the "hooks" directory inside the repository directory are the "hook
scripts". These scripts are executed by the Subversion server whenever a
particular action in Subversion happens. For example, there is a pre-commit
hook that is executed whenever someone tries to commit (check in) a change
in Subversion. This hook could, for example, see if a person formatted the
file they're checking in correctly, have certain attributes attached to it,
or even if they have permission to even make changes in the file.

There is also a post-commit hook that executes after a commit (check in) is
done and succeeds. The difference between pre and post hooks is simple: Pre
hooks can stop the particular action from taking place. By the time a post
hook runs, the transaction has already taken place.

Hooks are not unusual in a revision control system. Almost any modern
revision control system will have them and will either call them hooks or
triggers.

How does the hook script get its parameters? Simple, the Subversion server
passes the parameters to the hook script. It's very much like a get or post
method in HTML. Certain parameters are needed from the server, and the
server has a way of passing those parameters. In Subversion, they're passed
as part of the command line. When you write a Subversion hook script, you
know the order of the parameters for a particular hook script from the
documentation.

Subversion has the concept of properties. Again, many revision control
systems have similar concept and sometimes they're called "attributes". In
Subversion, a property is normally attached to a particular revision of a
particular file. You can create your own properties, but Subversion has
certain properties that are special. For example, the property svn:eol-style
sets whether the file requires a <LF>, a <CR>, or a <CR><LF> as a line
ending.

There are special properties that are not attached to a file, but to the
entire revision. These are called revision properties. Again, there are
special revision properties. For example, "svn:log" is the commit/check in
comment. The revision property "svn:author" is the person who checked in the
revision, and the "svn:date" is the date the revision was checked in.

Since normal properties are attached to a particular revision of a file,
they can't be changed because they're part of that revision of that file. If
someone changes a property, a new revision of that file (actually the whole
repository) is created: You have to check in a file's property change as you
would if you had changed the file itself. Because each revision of a file
can have a property, it is easy for me to see if someone changed a file
property and in what revision that change was made.

Revision properties, on the other hand, are a little more dangerous since
they can be changed, and there is no "backup" of what the change was. I
change a revision property, and there's no way to tell what the previous
value was.

This can be very dangerous. Three of the revision properties said who was
the author who checked in a change, when it was done, and why it was done. A
nefarious individual could change these properties and make it look like
someone else did a bad check in or could change a timestamp to prove they
actually made the deadline.

To prevent this from happening, there is a special hook called the
pre-revprop-change. This hook runs before a revision property can be
changed. It can then inspect a change in any of the revision properties and
prevent it from happening. For example, you might want to allow a developer
to change a commit comment. This could be useful if the developer made a
mistake in their comment during the commit and said it fixed bug #101 when
it fixed bug #1001.

Thus, you could have your pre-revprop-change hook allow a developer to
change svn:log (the checkin/commit comment), but only if their user ID
agrees with "svn:author" (the person who made the commit/checkin). You may
also want to prevent a user from changing svn:date or svn:author. The
default pre-revprop-change hook that you see probably does exactly this.

The pre-revprop-change hook is very different from the other pre-transaction
hooks like the pre-commit and pre-lock hooks. In other pre-transaction
hooks, if a particular hook is not active, there is nothing to prevent that
action from taking place. No pre-commit hook means that the user can do a
commit/check in. No pre-lock hook means the user can lock the file.

However, due to the nature of the revision properties, the default for this
hook in Subversion is different: You cannot change the revision properties
UNLESS there is a pre-revprop-change hook, and that pre-revprop-change hook
allows that transaction to take place.

Therefore, in order to change a revision property, you must have a file in
your "hooks" folder called "pre-revprop-change". This file must be
executable. And, this file must exit when called by the Subversion server
with an exit code of zero.

The svnsync command creates a duplicate repository by replaying the
transactions from one Subversion repository to another. It's pretty simple:
You need revision #100 to #120 from the main repository to be transferred to
the mirror repository. The svnsync program goes to revision #100 in the main
repository, finds the files that were changed. Then, it makes a new
Subversion revision in the mirror repository to duplicate those changes.
After svnsync does revision #100, it goes to revision #101 and does it again
until it gets to revision #120.

There's a slight problem: The "svn:log" messages are correct because the
svnsync can set those. However, when svnsync commits the transaction in the
mirror repository, the "svn:date" and "svn:author" on the mirror repository
don't match what was in the original repository. After all, the "svnsync"
process made the change (thus svnsync is the svn:author), and the change in
the mirror repository was made after the change in the original repository.
Thus, throwing off svn:date. Therefore, to make sure the mirror and original
repository absolutely match, the "svnsync" program has to change svn:author
and svn:date in the mirror repository to match the date and author in the
original repository.

But wait: In order to change these two revision properties, your mirror
repository needs a pre-revprop-change hook to allow it. You could simply
have a one line hook of "exit 0". This would certainly allow the svnsync
process to change svn:date and svn:author, but it would also allow anyone to
do it too. Therefore, you need a pre-revprop-change hook that allows svnsync
to make the change in svn:date and svn:author, but no one else.

If you look at http://svn.collab.net/repos/svn/trunk/notes/svnsync.txt, you
will see instructions for setting up a pre-revprop-change hook for svnsync
to work. Follow the directions, and you'll be fine.

Sorry for the long, convoluted explanation, but in order to explain what was
the issue you were having, you needed to understand what hook scripts were,
what the pre-revprop-change hook was, and how that was affecting svnsync.

Again, read the Subversion book at http://svnbook.com. It is really one of
the best written, clearest, and easiest to follow manuals I've seen on any
open source program. If all open source projects wrote manuals this clean,
nobody would have a reason to use Windows.

You can try the section in the book about Repository replication at <
http://svnbook.red-bean.com/en/1.5/svn.reposadmin.maint.html#svn.reposadmin.maint.replication>,
but it might not make much sense unless you have a basic understanding of
Subversion.

On Sun, Jul 26, 2009 at 4:51 PM, Richard Lichvar <rlichvar_at_sainc.com> wrote:

> Subversion 1.6 running under CentOS 5.3
>
>
>
> Trying to use svnsync to make a copy of a repository on a remote machine.
>
>
>
> Very new to SVN administration.
>
>
>
> Copied and then renamed the pre-revprop-change template in /hooks
>
>
>
> Not sure how to use this script. It appears to have several arguments.
> Where do those come from?
>
>
>
> An svnsynch init file:///path URL_of_repository_ being_clones
>
>
>
> Where ///path is the path to the new repository (created
> obviously with svnadmin)
>
>
>
> Yields the following error:
>
>
>
> “svnsync: 'pre-revprop-change' hook failed with error output:
>
> Changing revision properties other than svn:log is prohibited”
>
>
>
> Not being very familiar with SVN and, in particular, hook scripts, I need
> some advice/help on what to do here so I can follow up with a svnsynch synch
> (destination).
>
>
>
> Rich Lichvar
>
>
>

-- 
David Weintraub
qazwart_at_gmail.com
------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2375731
To unsubscribe from this discussion, e-mail: [users-unsubscribe_at_subversion.tigris.org].
Received on 2009-07-27 02:07:11 CEST

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.