Transcription of Notes on svn

This was converted from previous notes on cvs and may contain inaccuracies. There's a separate document dedicated to TortoiseSVN though notes on that can be found in here too.


Setting up svn...

Shell commands to get svn up and going. Put these into .bashrc:

	SVN_EDITOR=vim

Command-line

svn commands are all but identical to cvs.

How to check out/update

Note that the command,

	# svn co

does not obliterate changes already made to files in the subdirectory, probably by reason of the later modification date. Here we arbitrarily decide to call the VAS head directory vas. Click here for a development “movement” script I use (to get around the VAS development tree quickly).

	# mkdir vas                (on path /home/russ/vas)
	# svn co vintela-common    (on path /home/russ/vintela-common)
	# svn co -d vas VAS
	# svn add filename
	# svn commit filename

See also, Checking out (updating) a file....

Seeing only merged files during an update...

Here’s how to see only those files you’ve modified when updating everything from the respository.

	[email protected]:~/HEAD/VAS> svn update 2> /dev/null | grep ^M
	M src/libs/vaslicense/Makefile.am
	M src/libs/vaslicense/licensing-test.c
	M src/vastool/info.c
	M src/vastool/vasypd.c

This works because the normal crap that is already up-to-date comes out on stderr while the other on stdout.

Adding a new file or subdirectory...

A file is first added, then committed, then checked out.

	# svn add filename
	# svn commit filename

It’s acceptable to add more than one file or subdirectory name at a time.

However, new subdirectories do not need to be committed. You will get this message which you can ignore:

	# svn add directoryname
	# svn commit directoryname         # (no need to do this)
	svn commit: Examining directoryname

Committing (checking in) changes to a file...

Committing a change to a file (or just “committing a file”) is done thus:

	# svn commit filename

Updating (checking out) a file...

Merely updating the present tree; or update by erasing existing changes...

	# svn update
	# svn update -c

If files that have been changed aren’t erased first, then an M prompt will appear during update next to that file’s name. This indicates a “merge” which, if changes made by other parties are anywhere near the changed parts of the file in your filesystem, may not be accurately done. A simple U prompt means that the file has been added by someone else and by this update is created new in your filesystem while a P means that someone else updated it and it replaces what you have in your filesystem.

	[email protected]:~/vas/scripts> svn update
	Password:
	svn server: Updating .
	svn server: Updating aix
	svn server: Updating hpux
	svn server: Updating install
	P install/install-product.sh.in  # replaced
	M install/install.sh.in          # merged (someone else changed it and so have I)
	svn server: Updating linux
	svn server: Updating macosx
	svn server: Updating unix
	svn server: Updating upm
	svn server: Updating utils
	M utils/Makefile.am              # merged (I meant to throw away my changes)
	U utils/migrate-2_6-3_0.sh.in    # directory updated with new file
	svn server: Updating yptools

A ? prompt indicates that a file was found that is not under the control of svn nor is it noted by the svn:ignore property that tells svn when to shut up about missing (ignored) files.

Intermediate and final files in the subdirectory, created by the action of making or building, must be noted so that svn will not complain about them. For this purpose, the svn:ignore property is created in the subdirectory. You can migrate from cvs to svn using the .cvsignore file as input to the svn:ignore property thus:

	[email protected]:~/vas/scripts%gt; svn propset svn:ignore -F .cvsignore .

Checking for changes...

A quick check to see if anything has changed in the current subdirectory:

	# svn diff

Examining the log file/checking for differences...

Examining the log files for update owners and version numbers; displaying differences between the current and most recent update, and displaying differences between explicit, separate versions...

	# svn log filename
	# svn diff filename
	# svn diff -r version-number-1 -r version-number-2

THIS NEEDS REVISION FOR SVN

However, be careful: the latest version (near the top of the resulting dump) of a file isn’t also the latest for a given branch, but only (probably) for the main trunk. Make certain you understand what you’re looking at. One way is to examine the status of the file, e.g.: main.c here...

	[email protected]:~/dev/svn/docs/overviews> svn status
	?      groupwise-impl.png
	?      groupwise-impl.odg
	M      groupwise-impl.html
	M      archive-email.html

A ? prompt indicates that a file was found that is not under the control of svn nor is it noted by the svn:ignore property that tells svn when to shut up about missing (ignored) files. M means that this file needs to be committed.


Branching development trees...

The foregoing is the future VAS product. Just prior to release lock-down, the tree is branched. (Compare the commands below with the original VAS check-out command.) Here, we create a new subdirectory for the branched code tree, then check out into it where we’ll make careful changes from now until SP1 is released.

	# mkdir vas3sp1
	# svn co   -d vas3sp1   -r VAS_3_0_1_SP1_BRANCH   VAS

(Note: I’ve separated the arguments for this check-out command with white space and added bolding to make it all clearer.)

(And for VAS 2.6...)

	# mkdir vas26
	# svn co   -d vas26     -r VAS_2_6_SP5_BRANCH   VAS

From this point on, there is nothing special that needs to be done for changes made in either tree (vas or vas3sp1, etc.) to be effective in that tree. Bug fixes and enhancements must be made separately in each tree to which they are to apply.

The code and other files in vintela-common changes only rarely and this subdirectory serves every checked-out version of VAS alike. Or used to. This changed at some point.

Branching in svn...

To branch a repository, use the following command, for example:

	# svn rtag -b -f -r VAS_3_3_1_BRANCH VAS_3_3_2_BRANCH VAS VAS-openssl VAS-docbook vintela-common vintela-docbook VGP VGPdocs VASbuild

...where VAS_3_3_1_BRANCH was the original codebase to be branched (as opposed to just plain HEAD) and VAS_3_3_2_BRANCH is the new designation. There are 8 repositories; none can be neglected.

Next, go into each branched repository to change the version in configure.in, look for “AC_INIT”, and the build number build-number.txt, zero out this number so it starts over:

The last one, version.txt, isn’t rev’d unless the VAS library has changed enough to warrant getting bumped.


Retagging files...

Sometimes to fix a broken build that would be otherwise useless it is necessary to retag a later version of a file to get it included in the build. In this example, it was discovered that sshd.c had broken code that wouldn’t compile on Macintosh OSX. This was fixed and re-committed to svn. Then this command was issued to get it into build 85:

	[email protected]:~/VAS/src/preflight>: svn tag -F VAS_3_3_0_85 sshd.c

Bitchin’ and moanin’...

If svn bitches about checking in a previous version (let’s say you’re trying to cheat and do a hard, back-rev of a file by getting an older revision and committing that), go to subdirectory CVS, edit Entries, look for the file by name, and delete from the end of the line back to YYYY// where YYYY is the four-number year.

Alternatively, rename the file to something else, perform an update, delete the fresh copy and replace it with the edited file, then try again. Caution: ensure that no more recent version of the file has been committed.

Sometimes, both these exercises must be completed. This annoyance seems most frequent as soon as older versions of a file are got out of svn. It’s no doubt something for which there is a right way to do it, but no one around here seems to know what that is.


Using ssh-keygen to obviate svn passwords...

It’s possible to create an ssh key on your host (as well as on remote hosts), to make it so you don’t have to keep typing in your svn password:

	# cd
	# ssh-keygen -t rsa
	(take all the defaults)
	# cd .ssh
	# cat id_rsa.pub > authorized_keys

This doesn’t work for me yet, but I’m still getting information from someone who knows. I’m informed that I need to put a file onto the svn host (cvs.vintela.com), but which file and where?



Source-code check-out...

To get source code out into the local filesystem, do the following. There is an authentication step that will, initially, attempt to make use of the present user, in this case, russ, which may not be the one the repository knows about (indeed). In that case, log-in will fail and the opportunity to specify the correct user and password will be occasioned.

(And yes, this does show the folly of allowing Windoz-centric guys to go off creating names...)

	[email protected]:~/dev> mkdir svn
	[email protected]:~/dev> cd svn
	[email protected]:~/dev/svn> svn co https://svn.gwava.com/svn/retain/trunk retain
	[email protected]:~/dev/svn> svn co https://svn.gwava.com/svn/retain/Shared shared
	[email protected]:~/dev/svn> svn co https://svn.gwava.com/svn/retain/Docs\ and\ Utils docs

A great deal of time is spent on downloading the source code. It’s not a bad idea to limit the damage, but it's hard to avoid some of it.

What to do with this? Check out my Eclipse notes for Subversion usage.



Sample svn session...

To get svn on the local host, go looking for the subversion package (in YaST).

Sample svn session...

...while working on the PHP-VAS bindings.

Here, I check the files out of the repository...

	[email protected]:~> svn co svn+ssh://[email protected]/opt/svn/rc/php-vas/trunk php-vas
	Password:
	Password:
	Password:
	A    php-vas/LICENCE
	A    php-vas/example1.php
	A    php-vas/tests
	A    php-vas/tests/t_vas_attrs_find.php
	A    php-vas/tests/t_vas_user_init.php
	A    php-vas/tests/t_vas_krb5_get_principal.php
	A    php-vas/tests/t_vas_info_servers.php
	A    php-vas/tests/t_vas_info_domains.php
	A    php-vas/tests/checkAttribute.php
	A    php-vas/tests/t_vas_ctx_alloc.php
	A    php-vas/tests/driver
	A    php-vas/tests/t_vas_info_joined_domain.php
	A    php-vas/tests/t_vas_service_get_attrs.php
	.
	.
	.
	A    php-vas/tests/t_vas_err_clear.php
	A    php-vas/tests/driver.php
	A    php-vas/tests/t_vas_user_get_pwinfo.php
	A    php-vas/tests/t_vas_user_get_upn.php
	.
	.
	.
	A    php-vas/tests/t_vas_id_get_user.php
	A    php-vas/tests/t_vas_id_is_cred_established.php
	A    php-vas/configure.ac
	A    php-vas/bootstrap.sh
	A    php-vas/ChangeLog
	A    php-vas/scripts
	A    php-vas/scripts/vas.php
	A    php-vas/scripts/vas_ldap.php
	A    php-vas/scripts/vasapi.php
	A    php-vas/scripts/vas_gss.php
	A    php-vas/Makefile.am
	A    php-vas/doxvas.in
	A    php-vas/NEWS
	A    php-vas/extension
	A    php-vas/extension/config.m4
	A    php-vas/extension/vasapi.c
	A    php-vas/extension/php_vas.h
	A    php-vas/php-vas.pp
	A    php-vas/README
	Checked out revision 20.

...and here, I do some routine stuff. This first command can be done and set aside in a console somewhere to support work from then on.

	[email protected]:~/php-vas> ssh -MNC bricvsl01.prod.quest.corp
	Password:

	[1]+  Stopped                 ssh -MNC bricvsl01.prod.quest.corp
	[email protected]:~/php-vas> bg
	[1]+ ssh -MNC bricvsl01.prod.quest.corp &
	[email protected]:~/php-vas> svn diff vasapi.c
	[email protected]:~/php-vas> svn diff php_vas.h
	Index: php_vas.h
	===================================================================
	--- php_vas.h   (revision 7)
	+++ php_vas.h   (working copy)
	@@ -34,8 +34,8 @@
	 # define ZEND_VAS_ARG_INFO( name )          \
	         static zend_arg_info _info##name =  \
	         {                                   \
	-            name,                           \
	-            sizeof( name ) - 1,             \
	+            #name,                          \
	+            sizeof( #name ) - 1,            \
	             "", 0,                          \
	             0, 0, 0, 0, 0                   \
	         }
	[email protected]:~/php-vas> svn commit php_vas.h
	Password:
	Your password expires in 11 days. Please change it as soon as possible.
	Press Enter to Continue.
	Sending        php_vas.h
	Transmitting file data .
	Committed revision 8.


Deep sewage and snorkling...

...plus, svn trouble in Eclipse.

If repeated attempts to add, commit, update, etc. fail, there might be corruption. In this case, delete the parent directory and its contents. Then, re-do the update. That should clear it. If there were changes, they should be squirreled away in some form that can be reintroduced after sanity has returned.

If this doesn't work, try running svn by hand out in the filesystem. I did this:

	[email protected]:~/dev/svn/retain/RetainServer> rm -rf *
	[email protected]:~/dev/svn/retain/RetainServer> ll
	total 0
	[email protected]:~/dev/svn/retain/RetainServer> cd ..
	[email protected]:~/dev/svn/retain> svn co https://svn.gwava.com/svn/\
	                                      retain/trunk/RetainServer  RetainServer
	A    RetainServer/addlib
	A    RetainServer/addlib/servlet-api.jar
	A    RetainServer/addlib/jsp-api.jar
	A    RetainServer/test
	.
	.
	.
	A    RetainServer/web/User/browse_contents_main.jsp
	A    RetainServer/precompile.xml
	U   RetainServer

(Don't be confused by the command line wrapped here in order to fit on the page: the svn check out command takes a full source path followed by RetainServer—what I needed to call it because that's what it is in Eclipse.)

Then, in Eclipse, I did an update, which worked (showing that this solution works), but left a red stop sign error:

This went away as soon as I did a refresh.



Resolving conflicts in TortoiseSVN

When someone else has edited your file behind your back, (hehehe, there are legitimate reasons for this to happen), you can recover.

Right-click the file (in Windows File Explorer) and choose TortoiseSVN -> Edit Conflicts. This option is only present if, after update or merge, or you switch your working copy to a different URL, the other guy(s) changed the same few lines of the file (as you were editing).

What comes up is a side-by-side editor with colored lines, each color representing aspects of comparison (new lines, deleted lines, changed lines). In general, the lines your version of the file offer as different are in red (unless you've monkeyed with the color definitions).

You can right-click on the red-colored area (in the editor on the right side) and choose to merge the change into the final file you will commit.



Failure to commit

Using Tortoise SVN, I added a new subdirectory to a project, then attempted to commit it. I got this error report:

	Can't open file '/home/svn/Tmts/db/txn-current-lock': Permission denied.

Looking at the Linux box that hosts this repository, I see:

	[email protected]:/home/svn/Tmts/db> ll
	total 937
	-rw-rwSr-- 1 russ     subversion      3 2010-10-14 09:47 current
	-r--rwSr-- 1 www-data subversion     22 2010-10-11 17:53 format
	-rw-rwSr-- 1 www-data subversion   1920 2010-10-11 17:53 fsfs.conf
	-rw-rwSr-- 1 www-data subversion      5 2010-10-11 17:53 fs-type
	-rw-rwSr-- 1 www-data subversion      2 2010-10-11 17:53 min-unpacked-rev
	-rw-rwSr-- 1 www-data subversion 927744 2010-10-14 09:47 rep-cache.db
	drwxrwsr-x 3 www-data subversion     72 2010-10-11 17:53 revprops
	drwxrwsr-x 3 www-data subversion     72 2010-10-11 17:53 revs
	drwxrwsr-x 2 www-data subversion     48 2010-10-14 09:47 transactions
	-rw-rwSr-- 1 russ     subversion      2 2010-10-14 09:47 txn-current
	-rw-r--r-- 1 russ     subversion      0 2010-10-11 18:19 txn-current-lock
	drwxrwsr-x 2 www-data subversion     48 2010-10-14 09:47 txn-protorevs
	-rw-rwSr-- 1 www-data subversion     37 2010-10-11 17:53 uuid
	-rw-rwSr-- 1 www-data subversion      0 2010-10-11 18:17 write-lock

The problem is that when the new subdirectory was created, these synchronization files are created, but when it comes time to commit, they're still there and don't have the permissions set such that they can be used. The immediate solution was to change ownership and group attribution on them to match the others (www-data:subversion). I don't know what the long-term solution is yet; I'll have to keep doing this until I stumble upon that answer. (Read on...)

Sadly, when I attempt to add, then commit something from the Linux side, I get an analogous thing:

	[email protected]:~/dev/Tmts/dbscripts> svn add schema.sql
	A         schema.sql
	[email protected]:~/dev/Tmts/dbscripts> svn commit
	svn: Commit failed (details follow):
	svn: Can't open file '/home/svn/Tmts/db/txn-current-lock': Permission denied
	svn: Your commit message was left in a temporary file:
	svn:    '/home/russ/dev/Tmts/svn-commit.tmp'

Checking this directory again, I find now that the ownership and group attribution on the three files are okay, but...

	-rw-rwSr-- 1 www-data subversion      3 2010-10-14 09:47 current
	-rw-rwSr-- 1 www-data subversion      2 2010-10-14 09:47 txn-current
	-rw-r--r-- 1 www-data subversion      0 2010-10-11 18:19 txn-current-lock

...notice that group-write permission is missing from txn-current-lock. I set that and was able to commit.

	-rw-rw-r-- 1 www-data subversion      0 2010-10-11 18:19 txn-current-lock

How this works live

When I create a new object such as a directory remotely, that is, across HTTP, txn-current becomes owned by me. Upon committing it, the ownership of this file returns to www-data.

When I create a new object locally, that is, from Linux, this file doesn't change ownership. Then, when I commit it, I do acquire ownership over it.

This seeming chaos is benevolent. Whatever is going on, there is no more trouble with the repository as soon as the ownership and permission of the files noted above are fixed. Thereafter, operations by both local and remote clients proceed smoothly.