Skip to content

Instantly share code, notes, and snippets.

@ekkis
Created June 16, 2015 21:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ekkis/f30d6972d44ce170593d to your computer and use it in GitHub Desktop.
Save ekkis/f30d6972d44ce170593d to your computer and use it in GitHub Desktop.
Converts a CVS repository to Subversion, changing the layout
#!/usr/bin/perl
#
# svnrepo-layout-flip
# Copyright (C) 2009 Erick Calder
# All rights reserved.
#
# - Synopsis -
# the utility cvs2svn can convert an entire
# CVS repository to Subversion, but its choice
# of layout (pre-project) may not suit all users
# therefore this utility flips the hierarchy on its
# head to create a post-project layout
# e.g. /project/{trunk|tags|branches}
#
# - Syntax -
# svnrepo-layout-flip <username>/<password> [prune]
#
# - Notes -
# The environment variable DEBUG may be set
# to execute the script as a dry-run with
# debugging output
#
# - Metadata -
# $Revision: $
#
# - Licence -
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
$\ = $/;
($user, $pass) = split m|/|, shift
|| die "Please provide authentication: username/password";
$prune = shift;
$DEBUG = $ENV{DEBUG};
$SRV = "svn://localhost";
$SVNAUTH = "svn --username=$user --password=$pass";
$MSG = "-m 'svnrepo layout flip'";
for (qx/svn list -R $SRV/) {
chomp;
next if /\/$/ || /\/(trunk|tags|branches)$/;
s|/[^/]*?$||; $prj{$_} = 1;
}
for $needle (keys %prj) {
for $haystack (grep(/\Q$needle\E/, keys %prj)) {
delete $prj{$haystack} if $haystack ne $needle;
}
}
if ($DEBUG > 1) {
print "$_ = $prj{$_}" for sort keys %prj;
}
for (grep(/trunk/, keys %prj)) {
($prj{$_} = "$_/trunk") =~ s|/trunk||;
($re = $_) =~ s/trunk/(.*)/;
next if $re =~ /\(\.\*\)$/;
for (grep(/tags|branches/, keys %prj)) {
($prj{$_} = "$_/$1") =~ s|/$1|| if /$re/;
}
}
for (keys %prj) {
delete $prj{$_} if $prj{$_} == 1 || $_ eq $prj{$_};
}
for (sort keys %prj) {
print "$_ => $prj{$_}";
($path = $prj{$_}) =~ s|/[^/]*?$||;
svnmkdir($path);
sys(sprintf("$SVNAUTH mv $MSG $SRV/%s $SRV/%s", $_, $prj{$_}));
}
# sorting backwards allows us to get to nested directories
# so top directories are empty by the time we process them
if ($prune) {
for (qx/svn list -R $SRV |sort -r/) {
chomp;
print("Prune: $_"), sys("$SVNAUTH rm $MSG '$SRV/$_'")
unless qx(svn ls "$SRV/$_");
}
}
sub sys {
local $_ = shift;
print, return if $DEBUG;
! system($_) || die;
}
sub svnmkdir {
local $_ = shift;
local $path = "";
for (split m|/|) {
sys("$SVNAUTH mkdir $MSG $SRV/$path/$_")
unless qx(svn ls "$SRV/$path" |grep "$_/");
$path .= "$_/";
}
print "svnmkdir: $path" if $DEBUG;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment