Subversion for Advanced Users
THIS IS A DRAFT
This text may not be complete.
Subversion for Advanced Users
Subversion for Advanced Users Training Materials
Copyright Notice
Copyright © 2004-2023 by NobleProg Limited All rights reserved.
This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise.
Quite good book on the web ⌘
http://svnbook.red-bean.com/en/1.8
Agenda ⌘
- History (RCS, CVS, Subversion, DVCSs e.g. Git)
- Copy-Modify-Merge vs Lock-Modify-Unlock and guidelines
- SVN architecture and URL types
- Branching, cheap copies, reverts, merges, cherrypick
- Repository structures and svnmucc, guidelines
- Revision review (emails, RSS, scripts)
- Blaming, annotation and delegation based on the information
- Properties, built-in properties, custom properties, revision properties
- Hooks
- SVN repository syncing, backup, etc.
- CMS, Bug tracking
History ⌘
- RCS (Revision Control System)
- CVS (Concurrent Versions System)
- Subversion
- DVCS (Git, Bazaar, Darcs, etc.)
RCS ⌘
Short demo of the following commands:
- ci
- co
- rlog
- rcsdiff
Basic ideas are already there:
- separate working file and repository file
- RCS/ directory to gather repository files
- but no multiple users/machines
- but no handling of multiple files together
- and version numbers (branching) are very barebone and cumbersome to use
CVS ⌘
Implementing a client/server model on top of RCS files. The client is also capable of working on multiple files, but in an atomic operation.
Also, the client-server model favors the copy-modify-merge method instead of locking (as with RCS) and that is the default usage.
Was very widespread in the 90s and 00s, but from today's point of view it misses a lot of features: file renames, revisions for set of files, symbolic link handling, cheap branches, distributed version control, no support for binary files.
But then again, a big improvement over CVS and a very successful client/server system.
Subversion ⌘
First released in 2000, a very successful backward compatible system to CVS that aims to fix the most important issues.
The corporate world has also started to adopt Subversion. A 2007 report by Forrester Research recognized Subversion as the sole leader in the Standalone Software Configuration Management (SCM) category and as a strong performer in the Software Configuration and Change Management (SCCM) category.
From Wikipedia
Features:
- atomic commits over multiple files (versioning for directories),
- rename/copy/delete retains history,
- versioning for symlinks and for generic metadata,
- binary diff,
- mature client/server design: multiple protocols, authorization,
- efficient design, costs proportional to change size not to data size.
Git and other DVCSs ⌘
The most used DVCS today is clearly Git.
Designed by Linus Torvalds himself to replace BitKeeper usage for the Linux kernel.
Compared to SVN, the big difference is that the repository itself is distributed: every version control operation can be executed without network access to the server (or other copies of the repository).
Network access is only needed to sync between the repositories.
So DVCS systems are very suitable for highly distributed teams with the possibility of offline work.
Copy-modify-merge ⌘
Exercise:
- create a subversion repository on the Linux server,
- create an initial file revision for it,
- start svnserve to serve the repository,
- checkout from windows,
- work concurrently on the same file from Windows and Linux,
- resolve conflicts and get agreed on a common repository content,
- create a situation where things can be automerged.
Guidelines ⌘
Before starting some work always do an svn update.
Before committing, do an svn update in the project root, test the whole project and then commit.
After commit, do an svn update in the root of the project.
Lock and Unlock ⌘
Same exercise as before, but this time use lock and unlock.
svn lock svn unlock svn info svn status -u svn status -u -v svn unlock --force svn lock --force
svn commit also unlocks.
SVN URL types ⌘
- file:///home/user/... (Direct repository access to local or network drive.)
- http:// (Access via WebDAV protocol to Subversion-aware Apache server.)
- https:// (Same as http://, but with SSL encryption.)
- svn:// (Unencrypted TCP/IP access via custom protocol to an svnserve server.)
- svn+ssh:// (Encrytped TCP/IP access via custom protocol to an svnserve server.)
On windows to specify a drive letter:
- file:///X:/path/to/repos
Branches and tags ⌘
They are really all just copies.
Keep in mind:
- subversion can check out any part of the repository,
- copies are cheap because of copy-on-write.
So we will just investigate some simple repository setups to see how this all comes together.
Most simple setup ⌘
Whole project at the top-level.
This totally works, this is what we used in our simple copy-modify-merge and lock-unlock exercises, but...
It doesn't support tagging and branching, because if the whole project is at the top-level, then there is no place left for the tags and branches.
trunk/ branches/ tags/ ⌘
The usual solution is to have the following top-level directories:
- trunk/: for the main development tree, this is usually where all the development go.
- branches/: for implementing features that needs to be done separately from the main trunk development tree. E.g. the feature is complex and it needs more than one commit and we want to merge it back in one go.
- tags/: for released versions of a software product that will not change in the future, but would be useful to checkout sometime later.
So brances and tags are just copies of trunk, where tags means "one-time copy" and branch means "moving copy".
Branch exercises ⌘
Checkout the abcde repository served from the trainer's server.
Look around just to get familiar, understand the different tags/ and branches/ directories.
Then in another directory checkout only trunk and do the following:
- create a server side copy operation from trunk -> tags/2.5.5.1,
- switch to that tag,
- create a feature branch from trunk,
- switch to that branch,
- and develop some new "feature".
Branching exercises 2 ⌘
Continue the exercise by:
- fix some "bug" in the trunk and commit,
- merge this bugfix to the feature branch,
- continue to "develop" the feature,
- merge the feature back to trunk.
Problems with local copies ⌘
Is that they can be very slow, because all the data will have to travel the wires. For branch and tags creation you should always use server operations, which are more efficient.
On the other hand, it's totally OK to use svn copy locally just to save stuff, or create different copies while playing around with ideas without committing.
Repository structures ⌘
Repository structures 1 ⌘
- Root
- Module A
- trunk/, tags/, branches/
- Module B
- trunk/, tags/, branches/
- Module A
And users usually checkout and work inside one module.
Most common layout.
Repository structures 2 ⌘
- trunk
- Module A
- Module B
- tags
- Module A
- Module B
- branches
- Module A
- Module B
Here it's easy to checkout everything at once and do commits in one revision between multiple modules.
Back to structure 1 and svnmucc ⌘
- Root
- Module A
- trunk/, tags/, branches/
- Module B
- trunk/, tags/, branches/
- Module A
But what if we want to branch multiple modules or commit multiple file changes between modules in one revision using this structure?
We can either checkout the whole root and do it by hand, or if that is not feasible we can use svnmucc!
Exercise it!
Guidelines ⌘
- create branch by server copy operations, not in a local checkout;
- when developing on a feature branch or development branch:
- occasionally keep yourself updated with trunk (svn merge ^/trunk),
- when integrating a branch back to trunk (svn merge ^/branch/myfeature), first integrate trunk to the branch;
- before any merge, clean up your working copy and do an svn update.
Cherry pick and revert merges exercises ⌘
- Do a cherry pick bugfix from trunk to a release branch. This is called the release branch pattern.
- Revert a commit by using the cherry pick with negative number feature.
Revision review ⌘
Write a script that:
- uses direct svn access (no working copy),
- gets all the log messages for the previous day,
- and lists them on the screen.
In a real system we could also email them out to a mailing list of course.
Revision review with RSS ⌘
Exercise:
- download http://el-tramo.be/svnfeed/
- use it to generate a simple feed and share it through public_html
Blaming, annotation ⌘
Getting a line-by-line annotation of authorship and age of a file:
svn blame svn blame -v
Properties ⌘
Provides versioned metadata on the stored files and directories.
Provides unversioned metadata for revisions (e.g. log, author, date).
svn: prefixed properties are builtin:
- svn:executable
- svn:ignore
- svn:global-ignores
- svn:keywords
- svn:needs-lock
Ignore files ⌘
- svn:ignore
- svn:global-ignores
Executable files ⌘
- svn:executable
Try adding something that is already executable -> automatically works.
Keywords property ⌘
svn:keywords
- Date
- Revision
- Author
- HeadURL
- Id
- Header
svn export --ignore-keywords
Lock enforcement ⌘
svn:needs-lock
Revision properties ⌘
Unversioned metadata on revisions:
svn commit -m "Fix up the last remaining known regression bug." \ --with-revprop "test-results=all passing" svn log --with-all-revprops --xml svn propset -r 15 --revprop svn:author "errge@computer"
Custom company properties ⌘
Example commands:
svn propset license -F /path/to/LICENSE calc/button.c svn propedit copyright calc/button.c svn propset copyright '(c) 2006 Red-Bean Software' calc/* svn proplist -v calc/button.c svn propdel license calc/button.c (not the same as setting to empty string)
Automatic property setting and inherited properties ⌘
Every property can be inherited (since version 1.8) from directories to files if we specify --show-inherited-props to list or get.
Especially useful is the svn:auto-props property.
Properties guideline ⌘
Don't get crazy with this metadata stuff.
Look into other solutions too. Maybe some policy on how to format file headers or commit messages is more appropriate. Think about what happens to metadata if you export the project from subversion. Think about how you will search in them.
Subversion hooks ⌘
Hooks are small scripts/programs run on the server for various operations:
- send email that a commit happened,
- check if the commit message contains a bug number, reject otherwise,
- allow/disallow locking for specific users,
- allow/disallow svn log editing for specific users.
Hook types ⌘
Hooks are small scripts/programs run on the server for various operations:
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.start-commit.html
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.pre-commit.html
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.post-commit.html
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.pre-lock.html
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.post-lock.html
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.pre-unlock.html
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.post-unlock.html
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.pre-revprop-change.html
- http://svnbook.red-bean.com/en/1.8/svn.ref.reposhooks.post-revprop-change.html
Hooks on Windows have to end with .bat or .exe, on Linux they have to be executable.
General usage of already shipped hooks ⌘
For Linux there are example hook scripts in repo/hooks.
Path-based access control 1 ⌘
http://svnbook.red-bean.com/en/1.8/svn.serverconfig.pathbasedauthz.html
[groups] calc-developers = harry, sally, joe paint-developers = frank, sally, jane admins = root, admin everyone = @calc-developers, @paint-developers, @admins
[calc:/branches/calc/bug-142] harry = rw sally = r
# give sally write access only to the 'testing' subdir [calc:/branches/calc/bug-142/testing] sally = rw
[calc:/branches/calc/bug-142/secret] harry =
[calc:/trunk] @calc-developers = rw
# match every /old patch in every repostories [/old] * = @admins = rw
# give at least read access to everything [/] * = r
# regarding to paths: most specific wins # regarding to groups and users: the accesses are merged [paint:/projects/paint] jane = r @paint-developers = rw # so jane still has rw access
Path-based access control 2 ⌘
aliases, etc.
[aliases] harry = CN=Harold Hacker,OU=Engineers,DC=red-bean,DC=com sally = CN=Sally Swatterbug,OU=Engineers,DC=red-bean,DC=com joe = CN=Gerald I. Joseph,OU=Engineers,DC=red-bean,DC=com
[groups] calc-developers = &harry, &sally, &joe paint-developers = &frank, &sally, &jane everyone = @calc-developers, @paint-developers
Path-based access control 3 ⌘
Since version 1.5
[calendar:/projects/calendar] $anonymous = r $authenticated = rw
[calendar:/projects/calendar] ~$authenticated = r ~$anonymous = rw
[groups] calc-developers = &harry, &sally, &joe calc-owners = &hewlett, &packard calc = @calc-developers, @calc-owners
# Any calc participant has read-write access... [calc:/projects/calc] @calc = rw
# ...but only allow the owners to make and modify release tags. [calc:/projects/calc/tags] ~@calc-owners = r
Externals ⌘
http://svnbook.red-bean.com/en/1.8/svn.advanced.externals.html
$ svn propget svn:externals calc ^/sounds thirdparty/sounds /anotherproj@148 etc/anotherproj
SVN backup, synchronization, offline server ⌘
- svnsync: for keeping a readonly (initially empty) repository copy up-to-date with a repository;
- svnadmin hotcopy: to create a copy in production;
svnadmin hotcopy c:\repositories\exercise c:\svnbackup\exercise
- svnadmin dump: to dump (a hotcopy or a normal repo) into a dump file;
svnadmin dump c:\svnbackup\exercise > c:\svnbackup\exercise.dmp
- svnadmin load: load back the dumpfile into any subversion.
svnadmin create c:\repositories\exerciseNew (or create in VisualSVN repo manager, add permissions) svnadmin load c:\repositories\exerciseNew < c:\svnbackup\exercise.dmp
- svndumpfilter: for filtering repository history in dumps (see http://svnbook.red-bean.com/en/1.8/svn.reposadmin.maint.html#svn.reposadmin.maint.filtering)