8/25/2010

My subversion svn notes

Non-comment lines of $HOME/.subversion/config (%APPDATA%\Subversion\config on Windows):

global-ignores = *.ipr *.iml *.iws .project .classpath .settings .*.swp out.txt todo.txt *.save *.my *.class *.org #*# .*.rej *.rej .*~ *~ .#* .DS_Store
enable-auto-props = yes
*.java = svn:eol-style=native;svn:keywords=Date Author Id Revision HeadURL
To view the usage of a subcommand, for example, propedit:
svn help propedit
To view the details of a commit with rev number, including changed files and log messages (Without -v option, changed files are omitted in the output):
svn log -v -c 1234 Foo.java

# shows all changes made by rev 1234 compared to previous rev
svn diff -c 1234 Foo.java
To get, or set end-of-line property (One of 'native', 'LF', 'CR', 'CRLF'):
svn pg      svn:eol-style Utils.java
svn pget svn:eol-style Utils.java
svn propget svn:eol-style Utils.java

svn propset svn:eol-style LF Utils.java
svn pset svn:eol-style LF Utils.java
svn ps svn:eol-style LF Utils.java
To view the svn:externals or svn:ignore for the current directory:
svn propget svn:externals .
svn pg svn:externals .
svn pg svn:ignore .
To delete the svn:ignore for the current directory:
svn pd svn:ignore .
To edit the externals for the current directory:
svn --editor-cmd vim propedit svn:externals .
svn --editor-cmd vim pe svn:externals .
If any one of these environment variables SVN_EDITOR, VISUAL or EDITOR is set, you can omit the "--editor-cmd vim" part:
setenv EDITOR vim (in csh/tcsh)
export EDITOR=vim (in bash)
svn pe svn:externals .
To compare two different versions of a file:
svn diff -r r99:r100 build.xml
svn diff -r 99:100 build.xml
svn diff -c 100
It's easier to copy r99 r100 from svn log output, so I prefer the first form. The option "-c 100" is the same as "-r 99:100", and shows all changes made by rev 100.

To skip any differences in deleted files:
svn diff --no-diff-deleted
svn diff will not included newly added files, or files that are moved to target directory. To view colored diff with vim:
svn diff | view -
I also have a shell script wrapper (diffv) for the above:
#! /bin/sh
svn diff -x -wub $@ | view -
# use -x -wub to ignore whitespace changes
To get detailed info like URL, repository URL, revision, last changed date, etc:
svn info .
To relocate a loca workspace after the server repository has moved:
cd root-of-current-workspace
svn switch --relocate http://old http://new .
To revert all modified files under current directory:
svn revert *
svn revert util/*
Note that "svn revert ." does not revert changes in sub-directories. For recursive revert,
svn revert --depth infinity util
svn revert -R util
svn revert --recursive util

To downgrade svn client version:
cd {to the directory with local changes};
python $HOME/bin/change-svn-wc-format.py . 1.5
The above command will downgrade the working copy format to svn 1.5. This is to fix the annoying svn version error:
svn: This client is too old to work with working copy '...'.  You need
to get a newer Subversion client, or to downgrade this working copy.
See http://subversion.tigris.org/faq.html#working-copy-format-change
for details.
To apply a patch (.diff file), ignoring all parent directories in diff index:
cd {working directory containing the target file}
patch -i $HOME/Desktop/a.diff

To apply a patch (.diff file), preserving all parent directories in diff index:
cd {parent directory of the whole directory structure in diff index}
patch -p0 -i /tmp/a.diff
This is useful when target files do not fall under the same directory. -p means how many levels of directories to prune. patch is a Unix (not svn) command, usually resolves to /usr/bin/patch.


To make directories and parent directories together (the equivalent of OS command mkdir -p),
svn mkdir --parents com/a/b/c
To move a single file to another directory (--parents option will make any intermediate directories if not already exist):
svn mv --parents Utils.java ../common/a/b/c/Utils.java
# note that both SRC and DST must be file. If DST is a ../common/a/b/c,
# c will actually be treated as a file to hold the content of Utils.java

To move MULTIPLE files to another directory (--parents option will make any intermediate directories if not already exist):
cd <source directory>
svn mv --parents *.java ../common/a/b/c

To move the whole directory to another location:
svn mv impl ../common

After this command, if you do a "svn st", you will see all the deleted directories and files are listed, but under the DST directory, only the top-level directory (../common/impl) is listed as Added. Even in the comment editor window of "svn ci", still only the top-level directory listed as Added. How about files under the top-level directory, have they been copied over? But have no fear, everything from the SRC along with revision history were indeed moved to the destination. "svn ci" will commit these changes to the repository.

With TortoiseSVN (Windows only), all these move operations can be done in Windows Explorer: right-click the SRC, hold and drag it to the DST, and confirm your operation in the pop-up menu.

To remove a directory (there is no svn rmdir command),
svn rm a/
To merge some changes from trunk to branch, branch to trunk, or branch 1 to branch 2:
cd <source directory of changes>
svn log . | head -25
copy and paste the start rev and end rev, e.g., r123:r129
svn info; and copy the source URL, e.g., http://host:port/my-project-svn/a/b
cd <dest directory>
svn merge --dry-run -r r123:r129 http://host:port/my-project-svn/a/b
To make real changes, omit --dry-run option.

To merge ALL changes in Foo.java from trunk to branch:
cd <source directory of changes>
svn info Foo.java; and copy the complete source URL, e.g., http://host:port/.../Foo.java
cd <dest directory>
svn merge http://host:port/.../Foo.java ./Foo.java

To merge rev 567 in Foo.java from trunk to branch:
cd <source directory of changes>
svn info Foo.java; and copy the complete source URL, e.g., http://host:port/.../Foo.java
cd <dest directory>
svn merge -c 567 http://host:port/.../Foo.java ./Foo.java

To quickly undo or revert a bad commit (rev 99) with a reverse merge (notice the negative rev number is used. It must be a number; args like -c -r99 is rejected.):
svn merge -c -99 .
svn ci -m 'revert my changes in rev 99.'