A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Jump to

Quick reference

Showing posts with label svn. Show all posts
Showing posts with label svn. Show all posts

Advanced subversion usage

Rebase branch on trunk

cd /working/dir/path/to/branch

svn log --stop-on-copy | tail -4 | grep ^r | cut -d' ' -f1 | sed 's/r//'
1111

svn propget db:::dweb::trunk:last_merge_from /working/dir/path/to/branch
2222

svn merge -r 1110:2222 https://remote/path/to/trunk /working/dir/path/to/branch

# check for conflicts and test

svn commit -m'Pull from trunk'

Diff branch against trunk

svn propget db:::dweb::trunk:last_merge_from /working/dir/path/to/branch
1111

svn diff https://remote/path/to/trunk@1111 https://remote/path/to/branch

See all commit messages in svn log

After merging a branch to trunk, subversion does not include commit logs from branches in the trunk log. With a little work it can be persuaded to display the log in a more useful way, see "svnlogg" perl script below.

When viewing this log output you may want to see the diff of one of the changes and naively type:

    svn diff -c 69271

...this may produce no output. However, if you type this intead:

    svn diff -c 69271 https://www.example.com/repo/branches/feature_xyz

...then you will see the expected output.

How to determine the branch name from the commit message is left as an exercise for the reader.


"svnlogg" perl script:

#!/usr/bin/env perl

# First, get all the commits.
# -v shows the filenames of changed files,
# -g shows commits from all merged branches.

my $LOG_TEMP = "/tmp/log.txt";

system("svn log -v -g > $LOG_TEMP");

# Then split the list into individual commits, filter out ones we don't want to see, and sort by date:

open(my $fh,"<",$LOG_TEMP) or die "cannot open file $LOG_TEMP";
local $/="------------------------------------------------------------------------"; # define the record separator
my @a = <$fh>; # populate an array with the commit messages
foreach my $aa (
    sort {
        # sort the commits by date (descending)
        my ($c) = $a =~ /\s\|\s(\d\d\d\d\-\d\d\-\d\d)\s/; # extract date field
        my ($d) = $b =~ /\s\|\s(\d\d\d\d\-\d\d\-\d\d)\s/; #
        $d cmp $c
    } @a
) {
    # exclude unwanted messages, especially the hundreds of "remove svn:mergeinfo"
    # also exclude the commit messages we use by convention in our organisation
    # to refer to branches and merges
    if ($aa !~ /(remove svn:mergeinfo|branching|final pull)/i) {
        print "$aa\n";
    }
}

Depending on your hardware it may be unusably slow, so pipe it into a file for viewing later.

How to use git with an svn repo

Do you have a subversion repo? Think you're stuck with outdated subversion workflows? Not anymore! Use the fabulous git to work with your subversion hosted code:

git svn clone https://example.com/path/to/trunk -T trunk -b branches -t tags

(may take a long time with large repos, e.g. several days)

Now you can rebase your code! You can do all your work with git - easily branch, stash, rebase, blame, etc. - and when you're done, push back to subversion.

(source)

See subversion branches:
git branch -r

Update the git repo (may take several hours for large repos - you don't need to run this more than once):
git svn fetch --fetch-all

Update the current branch (run this on trunk/master instead of "fetch" above):
git svn rebase

(source)

svn basics, for git users

How to do stuff in subversion, when you're used to git:

# create a new branch
svn copy -m "Branching trunk" https://www.example.com/svn/repos/project/trunk https://www.example.com/svn/repos/project/branches/new_branch_name

# check out new branch
svn checkout https://www.example.com/svn/repos/project/branches/new_branch_name

# check status/diffs of working directory
svn status
svn diff

# show a specific commit
svn diff -c63197
svn diff -c63197 | vim -R -
svn diff -r63196:63197
svn diff -c63197 db/src/securesite/

# commit files
svn commit -m'Commit message' filename.ext

# see your changes after committing
svn update

# find where a branch was cut from trunk (svn equivalent of git mergebase)
# The last commit will be the first one in this branch after it was cut from trunk:
svn log -v --stop-on-copy

# cherry pick
svn merge -cXXXX trunk branch

# revert a commit
svn merge -c -REV .

Diff fun with vi and svn

Diff two files side-by-side
(search for this to highlight differences only -- replace ^I with actual tabs -- / <^I| <$| >^I| >$| \|^I )
diff --side-by-side [a] [b] | less

Diff two files side-by-side using vi
(use Ctrl-W+W to switch sides; may need :syntax off to prevent colours clashing)
vimdiff [a] [b]

Subversion diff using vi
Step 1. Create a diff command script for svn (and set the execute bit):
#!/bin/sh
# Subversion provides the paths we need as the sixth and seventh parameters.
LEFT=${6}
RIGHT=${5%    (working copy)}
[ "$RIGHT" == "$5" ] && RIGHT=$7
# Call the diff command (change the following line to make sense for your merge program).
# diffopt+=iwhite ignores whitespace differences
# \<c-w>\<c-w> switches to the right-hand pane
vimdiff "+set diffopt+=iwhite" '+execute "normal \<c-w>\<c-w>"' $LEFT $RIGHT


Step 2. Create a diff script for you to use:
#!/bin/bash
# Call the diff command (change the following line to make sense for your merge program).
# "-x -w" ignores all whitespace
svn diff -x -w --diff-cmd /path/to/diff/command/script/above $1


Step 3. Run the diff script
name_of_your_script [file in workspace]

How to checkout hosted subversion project

Google code:

svn checkout https://example.googlecode.com/svn/trunk/ example_directory --username example@gmail.com

Assembla:

svn checkout https://subversion.assembla.com/svn/example/ example_directory --username your_username


svn: Files skipped

Is subversion displaying a message that some files/directories were "skipped" ?
If you are using symlinks, try cd'ing into the directory, or using the full path instead.

How to install subversion on your linux shared hosting account

  1. Find out which linux distro your web host is running
  2. Download a set of subversion binaries for that linux distro
    1. or install that linux distro on a VM and compile into a PREFIX directory
  3. Copy bin/svn and require libs onto your web host (see list below for svn 1.6.16)
  4. Voila!


List of libs required for svn client:
svntest/lib/libsvn_ra-1.so.0
svntest/lib/libssl.so.0.9.8
svntest/lib/libsvn_diff-1.so.0
svntest/lib/libneon.so.27
svntest/lib/libsvn_ra_neon-1.so.0
svntest/lib/libsvn_subr-1.so.0
svntest/lib/libsvn_ra_local-1.so.0
svntest/lib/libsvn_wc-1.so.0
svntest/lib/libsvn_ra_svn-1.so.0
svntest/lib/liblber-2.4.so.2
svntest/lib/libsvn_fs_util-1.so.0
svntest/lib/libsvn_delta-1.so.0
svntest/lib/libldap-2.4.so.2
svntest/lib/libcrypto.so.0.9.8
svntest/lib/libsvn_fs_fs-1.so.0
svntest/lib/libsvn_fs-1.so.0
svntest/lib/libapr-1.so.0
svntest/lib/libserf-0.so.0
svntest/lib/libaprutil-1.so.0
svntest/lib/libgdbm.so.3
svntest/lib/libsvn_ra_serf-1.so.0
svntest/lib/libsvn_client-1.so.0
svntest/lib/libsvn_repos-1.so.0

Subversion on a Mac 10.4 (Tiger), behind a firewall

The Subversion project recommends:
  • THIS ONE WORKS: MacPorts - has a .dmg installer for 10.4 
    • need to set environment variable http_proxy if behind a firewall
    • then the sudo port -v selfupdate command
    • then do sudo port install subversion 
    • Warning: The installed version of Xcode (2.3) is known to cause problems. Version 2.5 or later is recommended on Mac OS X 10.4. Download Xcode tools.
  • Fink - wouldn't install for me, saying "Cannot perform symlink test on this volume because of a permissions problem". Running "Repair Disk Permissions" utility as recommended doesn't help at all.
  • Apple's Developer Tools - I don't think it's on the CD. Couldn't find a list of apps anywhere. When I tried, it installed a lot of stuff but I couldn't see svn anywhere.
  • OpenCollabNet - ?

    Subversion basics

    # checkout / create a new project
    svn checkout https://example.googlecode.com/svn/trunk/ example --username [username]

    # submit a directory for the first time
    svn import newdir/ https://example.googlecode.com/svn/trunk/

    # see all modified files in project
    svn status -v

    # submit modified files
    svn commit

    # diff
    svn diff --diff-cmd diff -x -wB [filename]
    svn diff --diff-cmd diff -x --side-by-side [filename]

    # move or copy, keeping history
    svn mv [old file] [new file]
    svn copy [old file] [new file]

    # update your workspace to head
    svn up /your-workspace

    # update your workspace to a particular date
    svn up -r {2010-11-14} /your-workspace

    # ignore a file or directory
    svn propset svn:ignore [file or dir] [parent dir]