[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

svn-uupdate approaches



I looked at your svn-uupdate in svn-devscripts, but I was suprised at
your approach.

First of all, I cannot use the program, because I do not keep my sources
in a directory called trunk. My sources are in ~/src, which is pulled in
by a set of svn:externals from various locations in three subversion
repositories.

I also do not keep my orig tarballs in subversion, for reasons of both
space and bandwidth. I was suprised to find that your svn-uupdate required
this. It's especially bad that your script always uncompresses the tarballs,
then recompresses them, thus making them not quite pristine upstream source.
(I know, I know, the tarball inside is unchanged. Still.)

What really suprised me is that you don't use svn_load_dirs. For all its
warts, it is very useful, especially when upstream moves files around. I
also suspect that it is far more efficient than is your method. You run
one svn add or remove for every new or deleted file in the new upstream
source. Some of us have our subversion server on the other side of a
modem, and opening possibly hundreds of ssh connections is a pain.
svn_load_dirs prepares a wc and commits it in essentially one operation.
(If there are moves, it may need to do a few more operations.) Your
technique also won't properly handle files that were in the old upstream
version, are in the new one, but were deleted from the debian
repository. I belive it will re-add those files, whereas svn_load_dirs
will not.

I hope that your plan is to make the scripts in svn-devscripts as
repository layout neutral as possible. If so, let me describe an
approach that I have used to develop an alternative svn-uupdate.

The key to my approach is that I noticed that while one might have
many possible urls to the trunk of a package:

svn://.../package/trunk
svn://.../trunk
svn://.../trunk/package
svn://.../trunk/foo/bar/baz/package

Every one of these does imply a particular layout for the tags and
branches directories. The transformation is simple: Just replace "trunk"
with "tags" or "branches":

svn://.../package/tags
svn://.../tags
svn://.../tags/package
svn://.../tags/foo/bar/baz/package

So I wrote a svnpath program to do this transformation. It's a very
simple perl script, which I will attach. If it's run with no arguments,
it just returns the url for the current directory:

joey@dragon:~package/uqm>svnpath 
svn+ssh://kitenet.net/home/svn/uqm/trunk/uqm
joey@dragon:~/src/debhelper>svnpath 
svn+ssh://kitenet.net/home/svn/debhelper/trunk

If it's run with a parameter, it replaces the trunk with that parameter:

joey@dragon:~/src/debhelper>svnpath tags
svn+ssh://kitenet.net/home/svn/debhelper/tags
joey@dragon:~package/uqm>svnpath branches
svn+ssh://kitenet.net/home/svn/uqm/branches/uqm

I find this very useful in general packaging work, since it saves me
needing to type out long subversion urls all the time. And with this
simple program, a program like svn-uupdate can guess at the paths for
tags and branches, and get them right with ease. Of course there are
some variations. For example, I keep my latest upstream branch in
`svnpath branches`/upstream. (For debhelper this is
svn+ssh://kitenet.net/home/svn/debhelper/branches/upstream, while for
uqm, this is svn+ssh://kitenet.net/home/svn/uqm/branches/uqm/upstream.)

Still, you'll find that my svn-uupdate script only contains at most three
variables that may need to be customized. (And it'd not be hard to reduce this
to only two.) I put these up front, and they could also be controlled by
switches, to accomidate _really_ weird repo layouts.

# You may need to change these expressions to match your repo.
tagurl=`svnpath tags`/upstream_version_$upstream_version
oldupstreamurl=`svnpath tags`/upstream_version_$oldupstream_version
upstream_branch=`svnpath branches`/upstream

By virtue of using svn_load_dirs, my svn-uupdate implementation is
short, just 65 lines. By virtue of using svnpath, it is nearly
repository independant. It does lack a few features, like importing
tarballs and baz2 (it currently imports only unpacked directories). I'd
be glad to add these features though. I've attached the program to this
message; the most recent copy is svn://kitenet.net/joey/trunk/bin/svn-uupdate

-- 
see shy jo
#!/usr/bin/perl
# Work out paths in a subversion repository for branches or tags of the
# given directory. Works on current directory by default, or it can be given
# a path.

my $wanted=shift;

# Get the svn url of the current directory.
my $url = `svn info @ARGV| grep ^Url: | cut -d ' ' -f 2`;
if (! length $url) {
	die "cannot get url";
}

if (length $wanted) {
	# Now jut substitute into it.
	$url=~s!/(?:trunk|branches|tags)($|/)!/$wanted$1!;
}
print $url;
#!/bin/sh
# Updates a package in svn vs a new upstream directory.
# Run it in the current checkout of the package and its version number.
# TODO support unpacking tarballs to tmp dir
set -e
newdir=$1
upstream_version=$2
if [ ! -d $newdir ] || [ -z "$upstream_version" ]; then
	echo "Usage: svn-uupdate untarred-new-source upstream-version" >&2
	exit 1
fi

# Make sure this wc is clean.
if [ -n "`svn st`" ]; then
	echo "Working directory is not clean or up-to-date. Resolve and retry." >&2
	svn st
	exit 1
fi

dir=`pwd`
oldupstream_version=`dpkg-parsechangelog | grep Version: | cut -f 2 -d ' ' | cut -f 1 -d -`
tmp_workdir=$TMP/svn-uupdate.$$
origurl=`svnpath`

# You may need to change these expressions to match your repo.
tagurl=`svnpath tags`/upstream_version_$upstream_version
oldupstreamurl=`svnpath tags`/upstream_version_$oldupstream_version
upstream_branch=`svnpath branches`/upstream

# Set up the temp workdir. This is only needed because svn_load_dirs wants
# it. We could actually use the real workdir, but that would involve
# switching it to the old upstream version, and then back, which would
# waste network bandwidth. Instead, waste some disk. (There's something to
# be said for the idempotency of this approach, too.)
cp -a . $tmp_workdir
trap "rm -rf $tmp_workdir" 0 INT

# Switch workdir back to the previous upstream source. 
if ! svn switch $upstream_branch $tmp_workdir; then
	echo "Failed to switch to $upstream_branch" >&2
	exit 1
fi

# All the ugly/hard stuff is in here. I'm not letting it do tags as it
# does not understand my repo layouts.
svn_load_dirs $upstream_branch . $newdir -wc $tmp_workdir
rm -rf $tmp_workdir

# Create upstream version tag.
svn cp $upstream_branch $tagurl \
	-m "tagging new upstream version $upstream_version"

# Merge all changes that occurred between the two upstream releases into
# the working copy.
svn merge $oldupstreamurl $upstream_branch .

# Check for conflicts.
if [ -n "`svn st | grep ^C`" ]; then
	echo "** There were conflicts. Resolve them and commit." >&2
	svn st | grep ^C
else
	svn commit -m "merged changes between upstream releases"\
	              "$oldupstream_version and $upstream_version"
	echo "Update complete."
fi

Attachment: pgpnmulfXSTkp.pgp
Description: PGP signature


Reply to: