<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://training-course-material.com/index.php?action=history&amp;feed=atom&amp;title=Subversion_for_Administrators</id>
	<title>Subversion for Administrators - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://training-course-material.com/index.php?action=history&amp;feed=atom&amp;title=Subversion_for_Administrators"/>
	<link rel="alternate" type="text/html" href="https://training-course-material.com/index.php?title=Subversion_for_Administrators&amp;action=history"/>
	<updated>2026-04-24T06:47:11Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://training-course-material.com/index.php?title=Subversion_for_Administrators&amp;diff=85880&amp;oldid=prev</id>
		<title>Lsokolowski at 14:09, 20 May 2022</title>
		<link rel="alternate" type="text/html" href="https://training-course-material.com/index.php?title=Subversion_for_Administrators&amp;diff=85880&amp;oldid=prev"/>
		<updated>2022-05-20T14:09:47Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Cat|Subversion}}&lt;br /&gt;
{{SVN Links}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;slideshow style=&amp;quot;nobleprog&amp;quot; headingmark=&amp;quot;⌘&amp;quot; incmark=&amp;quot;…&amp;quot; scaled=&amp;quot;false&amp;quot; font=&amp;quot;Trebuchet MS&amp;quot; &amp;gt;&lt;br /&gt;
;title: Subversion for Administrators&lt;br /&gt;
;author: Bernard Szlachta (NobleProg Ltd), Lukasz Sokolowski&lt;br /&gt;
&amp;lt;/slideshow&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Subversion for Administrators ==&lt;br /&gt;
Subversion for Administrators Training Materials&lt;br /&gt;
&lt;br /&gt;
{{Can I use your material}}&lt;br /&gt;
&lt;br /&gt;
== Agenda ⌘==&lt;br /&gt;
* Repository Structure (trunk per project, many projects)&lt;br /&gt;
* Protocols (File Access, Standalone, Apache, SSH)&lt;br /&gt;
* Logging&lt;br /&gt;
* Lock administration&lt;br /&gt;
* Removing files from repository (svndumpfilter)&lt;br /&gt;
* Hooks&lt;br /&gt;
* Svnsync&lt;br /&gt;
* Upgrade/verify/dump/load/hotcopy&lt;br /&gt;
* Encrypted datatransfer&lt;br /&gt;
&lt;br /&gt;
== Setting up Subversion ⌘==&lt;br /&gt;
&lt;br /&gt;
* Choosing from connection-possiblilities (http://, https://, svn://, svn+ssh://)&lt;br /&gt;
* Choosing a repository structure (one Repository for all or one per project)?&lt;br /&gt;
* Choosing a permission structure (how many users and groups, who may read/write to which path/repository)?&lt;br /&gt;
&lt;br /&gt;
== Files structure in repo ⌘==&lt;br /&gt;
&lt;br /&gt;
* conf/&lt;br /&gt;
** This directory is a container for configuration files.&lt;br /&gt;
* db/&lt;br /&gt;
** This directory contains the data store for all of your versioned data.&lt;br /&gt;
* format&lt;br /&gt;
** This file describes the repository&amp;#039;s internal organizational scheme.&lt;br /&gt;
* hooks/&lt;br /&gt;
** This directory contains hook script templates and hook scripts, if any have been installed.&lt;br /&gt;
* locks/&lt;br /&gt;
** Subversion uses this directory to house repository lock files, &amp;lt;br&amp;gt;used for managing concurrent access to the repository.&lt;br /&gt;
&lt;br /&gt;
== Subversion Commands ⌘==&lt;br /&gt;
* svn&lt;br /&gt;
* svnadmin&lt;br /&gt;
* svnlook&lt;br /&gt;
* svnserve &lt;br /&gt;
* svn2cl&lt;br /&gt;
* svndumpfilter&lt;br /&gt;
* svnrdump&lt;br /&gt;
&lt;br /&gt;
=== svnadmin ⌘===&lt;br /&gt;
Tool for maintenance of repo&lt;br /&gt;
&lt;br /&gt;
Removing dead transactions&lt;br /&gt;
 svnadmin lstxns myrepos&lt;br /&gt;
 svnadmin rmtxns myrepos `svnadmin lstxns myrepos`&lt;br /&gt;
&lt;br /&gt;
Packing FSFS filesystems&lt;br /&gt;
 svnadmin pack /var/svn/repos&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== svnlook ⌘===&lt;br /&gt;
Tool for diagnostic purposes&lt;br /&gt;
* for examining the various revisions and transactions (which are revisions in the making) in a repository&lt;br /&gt;
* do not change the repo&lt;br /&gt;
* typically used by the repository hooks for reporting the changes that &lt;br /&gt;
** are about to be committed &lt;br /&gt;
** or that were just committed&lt;br /&gt;
&lt;br /&gt;
=== svnserve ⌘===&lt;br /&gt;
&lt;br /&gt;
simple standalone service&lt;br /&gt;
&lt;br /&gt;
=== svndumpfilter ⌘===&lt;br /&gt;
&lt;br /&gt;
to easily modify streams of Subversion repository history data by acting as a path-based filter&lt;br /&gt;
&lt;br /&gt;
=== svnrdump ⌘===&lt;br /&gt;
&lt;br /&gt;
svnadmin dump and svnadmin load subcommands, rolled up into a separate program&lt;br /&gt;
&lt;br /&gt;
== Repository Structure ⌘==&lt;br /&gt;
[[File:SvnArchitAdmin.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=== Repo Structure ⌘===&lt;br /&gt;
&lt;br /&gt;
Module, Project, Library, etc...&lt;br /&gt;
* Repository per project&lt;br /&gt;
* Modules in root&lt;br /&gt;
* Modules in trunk&lt;br /&gt;
** Modules tagged separately&lt;br /&gt;
** Modules tagged together&lt;br /&gt;
&lt;br /&gt;
==== Modules in root ⌘====&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[File:SvnModRootAdmin.png|200px]] || &lt;br /&gt;
* each module has to be checked out  separately&lt;br /&gt;
* commits can not span multiple modules&lt;br /&gt;
* tags can not  span multiple modules in single commit &lt;br /&gt;
* most common layout&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Modules in trunk ⌘====&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[File:SvnModTrunkAdmin.png|200px]] || &lt;br /&gt;
Modules tagged separately&lt;br /&gt;
* checkout of all modules is possible&lt;br /&gt;
* commits can span multiple modules&lt;br /&gt;
* tags can not  span multiple modules in single commit 	(workaround by 3rd party tools)‏&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Modules in trunk con&amp;#039;t ⌘====&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[File:SvnModTrunkTogAdmin.png|200px]] || &lt;br /&gt;
Modules tagged together&lt;br /&gt;
* checkout of all modules is possible&lt;br /&gt;
* commits can span multiple modules&lt;br /&gt;
* tags can span multiple modules in single commit&lt;br /&gt;
* maybe difficult to determine relevant modules of a tag&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SVN Backend ⌘==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! FileSystem [„fsfs“] !! Berkeley DB[„bdb“]&lt;br /&gt;
|-&lt;br /&gt;
| Data integrity || stable || Difficult to deploy, but extremely reliable&lt;br /&gt;
|-&lt;br /&gt;
| Robustness || robust || fragile (“wedged”)&lt;br /&gt;
|-&lt;br /&gt;
| Usable from a read-only mount || yes || no&lt;br /&gt;
|-&lt;br /&gt;
| Platform-independent storage || yes || no&lt;br /&gt;
|-&lt;br /&gt;
| Usable over network filesystems || yes || no&lt;br /&gt;
|-&lt;br /&gt;
| Repository size|| smaller || larger&lt;br /&gt;
|-&lt;br /&gt;
| Scalability: number of revision trees || Depends on OS/FS (fixed in SVN 1.5) || No problems&lt;br /&gt;
|-&lt;br /&gt;
| Large commits || faster || slower&lt;br /&gt;
|-&lt;br /&gt;
| Directories with many files || faster || slower&lt;br /&gt;
|-&lt;br /&gt;
| Group permissions handling (unix) || no problems || Umask problem&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Creating a repository ⌘==&lt;br /&gt;
you can create repositories in any empty directory:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;svnadmin create /path/to/repository&lt;br /&gt;
 &amp;gt;svnadmin create --fs-type fsfs /var/svn/repos&lt;br /&gt;
 &amp;gt;svnadmin create --fs-type bdb /var/svn/repos&lt;br /&gt;
&lt;br /&gt;
== Protocol Comparison ⌘==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!   !! http://  https:// !! svn:// !! svn+ssh://&lt;br /&gt;
|-&lt;br /&gt;
| authentication|| all apache auth methods|| CRAM-MD5, SASL|| SSH&lt;br /&gt;
|-&lt;br /&gt;
| useraccount|| private userfiles or any other auth method|| private userfiles or SASL|| system accounts&lt;br /&gt;
|-&lt;br /&gt;
| authorization|| path-based authorization|| path-based authorization|| no path-based authorization&lt;br /&gt;
|-&lt;br /&gt;
| encryption|| optional SSL|| optional SASL|| always SSH&lt;br /&gt;
|-&lt;br /&gt;
| logging|| special configured logs|| no logging|| no logging&lt;br /&gt;
|-&lt;br /&gt;
| interoperation|| WebDAV clients|| svn clients only|| svn clients only&lt;br /&gt;
|-&lt;br /&gt;
| web access|| limited support|| no support|| no support&lt;br /&gt;
|-&lt;br /&gt;
| speed|| slower|| faster|| faster&lt;br /&gt;
|-&lt;br /&gt;
| complexity|| fair|| simple|| fair&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Svnserve daemon ⌘==&lt;br /&gt;
Setting up Subversion as a standalone service just requires a simple command:&lt;br /&gt;
 &amp;gt;svnserve –d –r [path to repository|repositories]&lt;br /&gt;
&lt;br /&gt;
TEST:&lt;br /&gt;
 &amp;gt;svn ls svn://localhost/[reponame]&lt;br /&gt;
&lt;br /&gt;
== Windows Service ⌘==&lt;br /&gt;
 &amp;gt;sc.exe create svn &lt;br /&gt;
  binpath=&amp;quot;c:\svn\bin\svnserve –-service –r [path to repo]&amp;quot;&lt;br /&gt;
  displayname=&amp;quot;Subversion Server&amp;quot;&lt;br /&gt;
  depend= Tcpip&lt;br /&gt;
  start=auto&lt;br /&gt;
&lt;br /&gt;
== Svnserve authentication (1/4) ⌘==&lt;br /&gt;
3 files for authentication (in repo/config directory):&lt;br /&gt;
* svnserve.conf  - general configuration file&lt;br /&gt;
* authz – stores path based authentication data&lt;br /&gt;
* passwd – stores user/password combinations&lt;br /&gt;
&lt;br /&gt;
== Svnserve authentication (2/4) ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
svnserve.conf&lt;br /&gt;
[general]&lt;br /&gt;
anon-access = read&lt;br /&gt;
auth-access = write&lt;br /&gt;
password-db = passwd&lt;br /&gt;
authz-db = authz&lt;br /&gt;
realm = My First Repository&lt;br /&gt;
&lt;br /&gt;
controls what anonym users can do (read, write or none)&lt;br /&gt;
controls what authenticated users can do (again, read, write or none)&lt;br /&gt;
location of the password database&lt;br /&gt;
location of the authz-db&lt;br /&gt;
authentication realm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Svnserve authentication(3/4) ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
authz&lt;br /&gt;
[aliases]&lt;br /&gt;
[groups]&lt;br /&gt;
devs = user1, user2&lt;br /&gt;
[/foo/bar]&lt;br /&gt;
username =&lt;br /&gt;
[repository:/baz/fuz]&lt;br /&gt;
@devs = rw&lt;br /&gt;
&lt;br /&gt;
aliases can provide alternative names &lt;br /&gt;
groups of users &lt;br /&gt;
a path in repository. Next lines will be either aliases(&amp;amp;), groups (@) or users followed by either “r” for read, “rw” for read-write, or nothing for no access&lt;br /&gt;
repositoryname can be addressed with colon(:)&lt;br /&gt;
Same fileformat as for apache authzfile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Svnserve authentication(4/4) ⌘==&lt;br /&gt;
passwd&lt;br /&gt;
 [users]&lt;br /&gt;
 username = password&lt;br /&gt;
 username2 = password&lt;br /&gt;
&lt;br /&gt;
only a single user section&lt;br /&gt;
&lt;br /&gt;
username followed by password (in clear text!)&lt;br /&gt;
&lt;br /&gt;
== Exercise ⌘==&lt;br /&gt;
* Create repo in the /repo directory&lt;br /&gt;
* Create two directories harry and sally (use file protocol)&lt;br /&gt;
* Create two user sally/sally and harry/harry and grant access each user access to write their own directory&lt;br /&gt;
* Test it using svnserve –d and svn protocol&lt;br /&gt;
&lt;br /&gt;
== Apache (single repository) ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LoadModule dav_module      modules/mod_dav.so&lt;br /&gt;
LoadModule dav_svn_module  modules/mod_dav_svn.so&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;Location /svn&amp;gt;&lt;br /&gt;
  DAV svn&lt;br /&gt;
  SVNPath path/to/repository&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dav module must be loaded before dav_svn module (2)&lt;br /&gt;
dav svn module translates http-dav requests into svn operations&lt;br /&gt;
location on server where repository will be served&lt;br /&gt;
activation of svn dav module&lt;br /&gt;
path to Subversion repository to be served&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exercise ⌘==&lt;br /&gt;
Make /repo repository available at http://localhost/repo&lt;br /&gt;
&lt;br /&gt;
== apache (multi repos) ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Multi repository(without path based authorization):&lt;br /&gt;
&lt;br /&gt;
LoadModule dav_module      modules/mod_dav.so&lt;br /&gt;
LoadModule dav_svn_module  modules/mod_dav_svn.so&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;Location /svn&amp;gt;&lt;br /&gt;
  DAV svn&lt;br /&gt;
  SVNParentPath path/to/repositories&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dav module must be loaded before dav_svn module (2)&lt;br /&gt;
dav svn module translates http-dav requests into svn operations&lt;br /&gt;
location on server where repository will be served&lt;br /&gt;
activation of svn dav module&lt;br /&gt;
path to folder with Subversion repositories  to be served&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== apache authentication (1/3) ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Basic authentication (without path based authorization):&lt;br /&gt;
&amp;lt;Location /svn&amp;gt;&lt;br /&gt;
  DAV svn&lt;br /&gt;
  SVNParentPath path/to/repositories&lt;br /&gt;
  AuthType Basic&lt;br /&gt;
  AuthName &amp;quot;Subversion repository&amp;quot;&lt;br /&gt;
  AuthUserFile /path/to/http-auth-file&lt;br /&gt;
  Require valid-user&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
selection of authentication algorithm („Basic“ means password will not be encrypted)&lt;br /&gt;
the name of the authentication realm (will be shown on password entry)&lt;br /&gt;
file with user/passwords (use htpasswd to create file and add user/passwords)&lt;br /&gt;
only valid users can access this location&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== apache authentication (2/3) ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Basic authentication, anonym read access (without path based authorization):&lt;br /&gt;
&amp;lt;Location /svn&amp;gt;&lt;br /&gt;
  DAV svn&lt;br /&gt;
  SVNParentPath path/to/repositories&lt;br /&gt;
  AuthType Basic&lt;br /&gt;
  AuthName &amp;quot;Subversion repository&amp;quot;&lt;br /&gt;
  AuthUserFile /path/to/http-auth-file&lt;br /&gt;
&amp;lt;LimitExcept GET PROPFIND OPTIONS REPORT&amp;gt;&lt;br /&gt;
    Require valid-user&lt;br /&gt;
  &amp;lt;/LimitExcept&amp;gt;&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
makes exception for all http-DAV read operations, so anonymous user can read &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== apache authentication (3/3) ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Path based authorization :&lt;br /&gt;
LoadModule authz_svn_module   modules/mod_authz_svn.so&lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;Location /svn&amp;gt;&lt;br /&gt;
  DAV svn&lt;br /&gt;
  SVNParentPath path/to/repositories&lt;br /&gt;
  AuthType Basic&lt;br /&gt;
  AuthName &amp;quot;Subversion repository&amp;quot;&lt;br /&gt;
  AuthUserFile /path/to/http-auth-file&lt;br /&gt;
  Require valid-user&lt;br /&gt;
  AuthzSVNAccessFile /path/to/access/file &lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
need to load authz_svn module to enable path based authentication&lt;br /&gt;
location of authz accessfile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exercise ⌘==&lt;br /&gt;
Enforce the constraint that sally can access only /repo/sally folder and harry can access /repo/harry folder with apache&lt;br /&gt;
&lt;br /&gt;
== Logging (apache) ⌘==&lt;br /&gt;
apache webserver can be configured to log any Subversion high level operation. Place this line outside of a location section:&lt;br /&gt;
&lt;br /&gt;
CustomLog logs/svn_logfile &amp;quot;%t %u %{SVN-ACTION}e&amp;quot; env=SVN-ACTION&lt;br /&gt;
&lt;br /&gt;
The %t and %u are standard apache logging constants meaning time and user.&lt;br /&gt;
&lt;br /&gt;
Logging is only available on apache installations&lt;br /&gt;
&lt;br /&gt;
== svn+ssh ⌘==&lt;br /&gt;
* No special configuration required&lt;br /&gt;
* There is NO PATH-BASED authorization&lt;br /&gt;
* Good idea to use groups and&lt;br /&gt;
** umask 0002&lt;br /&gt;
** chmod g+ws&lt;br /&gt;
&lt;br /&gt;
== *Setting UP svn+ssh  ⌘==&lt;br /&gt;
# Install open-ssh server (e.g. apt-get install ssh)&lt;br /&gt;
# Setup a user if they don’t exists&lt;br /&gt;
# Create a group (e.g. groupadd grepo)&lt;br /&gt;
# Add the user to the group &lt;br /&gt;
#* e.g. usermod -a -G grepo ubuntu&lt;br /&gt;
# Change permission and ownership on the repo folders&lt;br /&gt;
#* chmod g+ws /repo –R&lt;br /&gt;
#* chown :grepo /repo -R&lt;br /&gt;
# Change default umask (e.g. in /etc/profile) to umask 0002&lt;br /&gt;
&lt;br /&gt;
== Exercise ⌘==&lt;br /&gt;
* Enable Logging as in the example show on the previous slide&lt;br /&gt;
* Test with commit and checkout commands&lt;br /&gt;
&lt;br /&gt;
== Apache PAM authentication* ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;
        ServerName svn.nobleprog.net&lt;br /&gt;
&amp;lt;Location /repo&amp;gt;&lt;br /&gt;
        AuthType Basic&lt;br /&gt;
        AuthName “Sample Repository&amp;quot;&lt;br /&gt;
        AuthPAM_Enabled On&lt;br /&gt;
        AuthGROUP_Enabled on&lt;br /&gt;
        Require group hitra&lt;br /&gt;
        AuthBasicAuthoritative off&lt;br /&gt;
        AuthUserFile /dev/null&lt;br /&gt;
        Require valid-user&lt;br /&gt;
        DAV svn&lt;br /&gt;
        SVNPath /repo&lt;br /&gt;
    &amp;lt;/Location&amp;gt;&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== lock administration ⌘==&lt;br /&gt;
As administrator you can always kill locks to all files:&lt;br /&gt;
To list locked files, you can use  the lslocks command:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;svnadmin lslocks /path/to/repo [path/inside/repo]&lt;br /&gt;
&lt;br /&gt;
To remove the locks use rmlocks&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;svnadmin rmlocks /path/to/repo path/to/locked/file&lt;br /&gt;
&lt;br /&gt;
== changing log messages ⌘==&lt;br /&gt;
Log Messages are not versioned, so changes to them will overwrite the old log message &lt;br /&gt;
&lt;br /&gt;
Only administrators with file-system access can change log-message using this command:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;svnadmin setlog {path/to/repo} -r REV MSG-FILE --bypass-hooks&lt;br /&gt;
&lt;br /&gt;
--bypass-hooks is important, as it will allow administrator to change revision without calling the hook »pre-revprop-change«&lt;br /&gt;
&lt;br /&gt;
Caution: old data is lost!&lt;br /&gt;
&lt;br /&gt;
You can allow client-side revision property changes by activating pre-revprop-change-hook&lt;br /&gt;
&lt;br /&gt;
== Exercise ⌘==&lt;br /&gt;
&lt;br /&gt;
Change the last revision log message to “I changed it”&lt;br /&gt;
&lt;br /&gt;
== Dump and Load ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
svnadmin create /repo1&lt;br /&gt;
svnadmin dump /repo &amp;gt; /tmp/dump&lt;br /&gt;
svnadmin load /repo1 &amp;lt; /tmp/dump&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Removing files from repository ⌘==&lt;br /&gt;
Subversion cannot remove files from repository, so if you really want to delete any trace of a file,&amp;lt;br&amp;gt; &lt;br /&gt;
you need to filter a dump and load it back to a new repository.&lt;br /&gt;
&lt;br /&gt;
[[File:SvnDelFileAdmin.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== svndumpfilter problems ⌘==&lt;br /&gt;
&lt;br /&gt;
svndumpfilter has problems with trailing slashes:&amp;lt;br&amp;gt;&lt;br /&gt;
If your dumpfile has trailing slashes your include/exclude argument &amp;lt;br&amp;gt;&lt;br /&gt;
must have trailing slashes also and vice versa.&lt;br /&gt;
&lt;br /&gt;
svndumpfilter has problems with copies:&lt;br /&gt;
As a copy must show their origin in Subversion it could happen &amp;lt;br&amp;gt;&lt;br /&gt;
that just its origin was filtered by svndumpfilter.&lt;br /&gt;
&lt;br /&gt;
This is a system immanent behavior of Subversion and cannot be changed.&lt;br /&gt;
&lt;br /&gt;
However there are a few rewritten dumpfilters with some quirks fixed:&lt;br /&gt;
&lt;br /&gt;
http://furius.ca/pubcode/pub/conf/bin/svndumpfilter3.html&lt;br /&gt;
&lt;br /&gt;
== svndumpfilter Example ⌘==&lt;br /&gt;
* Create a new repository with 3 Dirs:&lt;br /&gt;
** project_A&lt;br /&gt;
** project_B&lt;br /&gt;
** project_C&lt;br /&gt;
* and in each directory a file:&lt;br /&gt;
** file_a.txt&lt;br /&gt;
** file_b.txt&lt;br /&gt;
** file_c.txt&lt;br /&gt;
* Export repository to dumpfile:&lt;br /&gt;
** svnadmin dump {path/to/repo} &amp;gt; {path/to/dumpfile}&lt;br /&gt;
* run svndumpfilter (special windows syntax!):&lt;br /&gt;
** svndumpfilter exclude project_A &amp;lt; c:\dump.txt &amp;gt; c:\project_a_ex.txt&lt;br /&gt;
** svndumpfilter include project_A &amp;lt; c:\dump.txt &amp;gt; c:\project_a.txt&lt;br /&gt;
* compare the three dumpfiles&lt;br /&gt;
&lt;br /&gt;
== Exercise ⌘==&lt;br /&gt;
&lt;br /&gt;
* Split the repository into 2&lt;br /&gt;
** /harry_repo containing file:///repo/harry folder&lt;br /&gt;
** /sally_repo containing rest of the repository&lt;br /&gt;
&lt;br /&gt;
== Hooks ⌘==&lt;br /&gt;
&lt;br /&gt;
Hooks play an important role in customizing&amp;lt;br&amp;gt; &lt;br /&gt;
workflows and adapting Subversion for special needs.&lt;br /&gt;
&lt;br /&gt;
Hooks are triggered by special repository events&amp;lt;br&amp;gt;&lt;br /&gt;
and depending on the return value Subversion&amp;lt;br&amp;gt; &lt;br /&gt;
approves or cancels the action.&lt;br /&gt;
&lt;br /&gt;
The hook script’s environment is empty so you need absolute paths and set all needed variables explicitly.&lt;br /&gt;
&lt;br /&gt;
== Hooks con&amp;#039;t ⌘==&lt;br /&gt;
&lt;br /&gt;
There are 9 different types of hooks for 4 different events during commits:&lt;br /&gt;
&lt;br /&gt;
 commit hooks 		(start-commit, pre-commit, post-commit)&lt;br /&gt;
 lock hooks 		(pre-lock, post-lock)&lt;br /&gt;
 unlock hooks 		(pre-unlock, post-unlock)&lt;br /&gt;
 revprop-change hook 	(pre-revprop-change, post-revprop-change)&lt;br /&gt;
&lt;br /&gt;
Messages sent to stderr will be marshalled to the svn client. &lt;br /&gt;
&lt;br /&gt;
On pre- or start- hooks, returning a non-zero value usually cancels the action.&lt;br /&gt;
&lt;br /&gt;
== Commit Hooks ⌘==&lt;br /&gt;
&lt;br /&gt;
The commit is the only event which has 3 hooks:&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
start-commit(REPO_PATH, USER_NAME, CAPS) – from v 1.5&amp;lt;br&amp;gt;&lt;br /&gt;
This hook is called right before any data is transferred to the server. &amp;lt;br&amp;gt;&lt;br /&gt;
Useful for maintenance lock-down, or extra user-authentication.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
pre-commit(REPO_PATH, TXN_NAME)&amp;lt;br&amp;gt;&lt;br /&gt;
This hook is called right after data is transferred to the server, &amp;lt;br&amp;gt;&lt;br /&gt;
before the transaction is finished. &amp;lt;br&amp;gt;&lt;br /&gt;
Here you can check all different semantics by examinig the transaction. &lt;br /&gt;
Useful for enforcing workflows.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
post-commit(REPO_PATH, NEW_REVISION)&amp;lt;br&amp;gt;&lt;br /&gt;
This hook is called after transaction is complete, before acknowledge is sent back to client. &amp;lt;br&amp;gt;&lt;br /&gt;
Useful for sending notification mails.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commit hook example ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
check for empty commit message:&lt;br /&gt;
REPOS=&amp;quot;$1&amp;quot;&lt;br /&gt;
TXN=&amp;quot;$2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
SVNLOOK=/usr/local/bin/svnlook&lt;br /&gt;
$SVNLOOK log -t &amp;quot;$TXN&amp;quot; &amp;quot;$REPOS&amp;quot; | \&lt;br /&gt;
   grep &amp;quot;[a-zA-Z0-9]&amp;quot; &amp;gt; /dev/null || exit 1&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commit hook example in Windows ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files\TortoiseSVN\bin\svnlook.exe&amp;quot; log -t %2 %1 | FindStr [a-zA-Z0-9]&lt;br /&gt;
IF %ERRORLEVEL% EQU 0 GOTO OK&lt;br /&gt;
echo &amp;quot;Commit Comments are Required&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
exit 1&lt;br /&gt;
:OK&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== lock/unlock hooks ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
For customizing locking in Subversion you need lock/unlock hooks&lt;br /&gt;
&lt;br /&gt;
lock hooks:&lt;br /&gt;
pre-lock(REPOS_PATH, PATH, USER, LOCK_COMMENT, STEAL[1:0])&lt;br /&gt;
Here you can define workflows (e.g. disallow stealing locks, allowing locks only for certain files)&lt;br /&gt;
&lt;br /&gt;
post-lock(REPOS_PATH, USER) &amp;lt; locked path via stdin&lt;br /&gt;
Useful for notifications.&lt;br /&gt;
&lt;br /&gt;
unlock hooks:		&lt;br /&gt;
pre-unlock(REPOS_PATH, PATH, USER, TOKEN, BREAK:UNLOCK[1:0])&lt;br /&gt;
define workflow for releasing (breaking) locks, e.g. define administrator &lt;br /&gt;
who is allowed to break locks or notify previous lock-owner&lt;br /&gt;
&lt;br /&gt;
post-unlock()&lt;br /&gt;
Useful for notifications.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== revprop-change hooks ⌘==&lt;br /&gt;
 We strongly advise against enabling revprop-changes, as backup and recovery will be much more complex.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
revprop-change hooks:&lt;br /&gt;
pre-revprop-change(REPOS_PATH, REV, USER, PROPNAME, ACTION) &lt;br /&gt;
used for semantics to control who can change the revision properties. On stdin is the old property value&lt;br /&gt;
&lt;br /&gt;
post-revprop-change(REPOS_PATH, REV, USER, PROPNAME, ACTION)&lt;br /&gt;
used for notification and backup purposes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== revprop-change hook in windows ⌘==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
@ECHO OFF&lt;br /&gt;
:: Set all parameters. Even though most are not used, in case you want to add&lt;br /&gt;
:: changes that allow, for example, editing of the author or addition of log messages.&lt;br /&gt;
set repository=%1&lt;br /&gt;
set revision=%2&lt;br /&gt;
set userName=%3&lt;br /&gt;
set propertyName=%4&lt;br /&gt;
set action=%5&lt;br /&gt;
&lt;br /&gt;
:: Only allow the log message to be changed, but not author, etc.&lt;br /&gt;
if /I not &amp;quot;%propertyName%&amp;quot; == &amp;quot;svn:log&amp;quot; goto ERROR_PROPNAME&lt;br /&gt;
&lt;br /&gt;
:: Only allow modification of a log message, not addition or deletion.&lt;br /&gt;
if /I not &amp;quot;%action%&amp;quot; == &amp;quot;M&amp;quot; goto ERROR_ACTION&lt;br /&gt;
&lt;br /&gt;
:: Make sure that the new svn:log message is not empty.&lt;br /&gt;
set bIsEmpty=true&lt;br /&gt;
for /f &amp;quot;tokens=*&amp;quot; %%g in (&amp;#039;find /V &amp;quot;&amp;quot;&amp;#039;) do (&lt;br /&gt;
set bIsEmpty=false&lt;br /&gt;
)&lt;br /&gt;
if &amp;quot;%bIsEmpty%&amp;quot; == &amp;quot;true&amp;quot; goto ERROR_EMPTY&lt;br /&gt;
&lt;br /&gt;
goto :eof&lt;br /&gt;
&lt;br /&gt;
:ERROR_EMPTY&lt;br /&gt;
echo Empty svn:log messages are not allowed. &amp;gt;&amp;amp;2&lt;br /&gt;
goto ERROR_EXIT&lt;br /&gt;
&lt;br /&gt;
:ERROR_PROPNAME&lt;br /&gt;
echo Only changes to svn:log messages are allowed. &amp;gt;&amp;amp;2&lt;br /&gt;
goto ERROR_EXIT&lt;br /&gt;
&lt;br /&gt;
:ERROR_ACTION&lt;br /&gt;
echo Only modifications to svn:log revision properties are allowed. &amp;gt;&amp;amp;2&lt;br /&gt;
goto ERROR_EXIT&lt;br /&gt;
&lt;br /&gt;
:ERROR_EXIT&lt;br /&gt;
exit /b 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exercises ⌘==&lt;br /&gt;
* Copy pre-commit.tmpl file to pre-commit and test whether you can commit something without specifying a message&lt;br /&gt;
* Create &amp;#039;pre-revprop-change&amp;#039; hook and allow only to modify &amp;#039;svn:log&amp;#039; property&lt;br /&gt;
&lt;br /&gt;
== svnsync ⌘==&lt;br /&gt;
[[File:SvnSyncAdmin.png|600px]]&lt;br /&gt;
&lt;br /&gt;
== svnsync con&amp;#039;t ⌘==&lt;br /&gt;
&lt;br /&gt;
create mirror repository&lt;br /&gt;
 &amp;gt;svnadmin create /path/to/mirror&lt;br /&gt;
&lt;br /&gt;
create a pre-revprop-change hookscript in mirror repository&lt;br /&gt;
 &amp;gt;echo exit 0 &amp;gt; /path/to/mirror/hooks/pre-revprop-change&lt;br /&gt;
 &amp;gt;chmod +x /path/to/mirror/hooks/pre-revprop-change&lt;br /&gt;
&lt;br /&gt;
initialize mirror repository&lt;br /&gt;
 &amp;gt;svnsync init file:///path/to/mirror file:///path/to/repo &lt;br /&gt;
&lt;br /&gt;
synchronize repositories&lt;br /&gt;
 &amp;gt;svnsync sync file:///path/to/mirror &lt;br /&gt;
&lt;br /&gt;
== Backups – hot copy ⌘==&lt;br /&gt;
&lt;br /&gt;
copy a repository (even on a running server!) with the hotcopy command:&lt;br /&gt;
 &amp;gt;svnadmin hotcopy /path/to/repo /path/to/new/repo&lt;br /&gt;
&lt;br /&gt;
Note that hooks will be copied, too.&lt;br /&gt;
&lt;br /&gt;
[[File:SvnHotAdmin.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== Hot Copies ⌘==&lt;br /&gt;
Hotcopy copies the repository along with all other&lt;br /&gt;
file configurations, permissions, hooks and logs.&lt;br /&gt;
&lt;br /&gt;
* Hotcopy works on a running system regardless of running transactions&lt;br /&gt;
* Hotcopy creates an exact copy of a new repository which can be used as a backup.&lt;br /&gt;
* Hotcopy uses as much diskspace as the original repository.&lt;br /&gt;
* Hotcopies are faster to restore than dumpfiles.&lt;br /&gt;
&lt;br /&gt;
== Repository Integrity ⌘==&lt;br /&gt;
You should check the integrity of your repositories on a regular basis&lt;br /&gt;
&lt;br /&gt;
Use the verify command:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;svnadmin verify /path/to/repo&lt;br /&gt;
&lt;br /&gt;
== Dumps ⌘==&lt;br /&gt;
&lt;br /&gt;
* Dump is the secure way of exporting a repository with all history and versioning information.&lt;br /&gt;
* Human readable fileformat.&lt;br /&gt;
* Binary files exist inline so you should not edit the dump-file with your normal texteditor.&lt;br /&gt;
* Files are quite large but compress well.&lt;br /&gt;
* Through the --incremental switch dumps can be saved from revision to revision.&lt;br /&gt;
* Restoring a broken repository from a dump might take a long time.&lt;br /&gt;
&lt;br /&gt;
== Upgrading Repository ⌘==&lt;br /&gt;
&lt;br /&gt;
You can use a dump/load cycle to upgrade the repository format: &lt;br /&gt;
 &amp;gt;svnadmin create /new/repo&lt;br /&gt;
 &amp;gt;svnadmin dump /path/to/repo | svnadmin load /new/repo&lt;br /&gt;
[[File:SvnUpgrAdmin.png|400px]]&lt;br /&gt;
&lt;br /&gt;
== Upgrading con&amp;#039;t ⌘==&lt;br /&gt;
&lt;br /&gt;
Since svn 1.5 you can use the upgrade command to upgrade the repository format&lt;br /&gt;
 &amp;gt;svnadmin upgrade /path/to/repo&lt;br /&gt;
&lt;br /&gt;
[[File:SvnUpgr2Admin.png|400px]]&lt;br /&gt;
&lt;br /&gt;
This option is much faster, however, you will not get all server-side repository features.&lt;br /&gt;
&lt;br /&gt;
== GUI ⌘==&lt;br /&gt;
* Plugins&lt;br /&gt;
** subversive (eclipse plugin)&lt;br /&gt;
** netbeans, etc&lt;br /&gt;
* tortoise&lt;br /&gt;
* VisualSVN&lt;/div&gt;</summary>
		<author><name>Lsokolowski</name></author>
	</entry>
</feed>