/[svn2cvs]/trunk/svn2cvs.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/svn2cvs.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Tue Mar 9 20:58:34 2004 UTC (20 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 4621 byte(s)
initial import

1 dpavlin 1 #!/usr/bin/perl -w
2    
3     # This script will transfer changes from Subversion repository
4     # to CVS repository (e.g. SourceForge) while preserving commit
5     # logs.
6     #
7     # Based on original shell version by Tollef Fog Heen available at
8     # http://raw.no/personal/blog
9     #
10     # 2004-03-09 Dobrica Pavlinusic <dpavlin@rot13.org>
11    
12     use strict;
13     use File::Temp qw/ tempdir /;
14     use Data::Dumper;
15     use XML::Simple;
16    
17     # get current user home directory
18     my $HOME = $ENV{'HOME'} || die "can't get home directory!";
19    
20     # cvsroot directory
21     my $CVSROOT="$HOME/x/cvsroot";
22     # name of cvs repository to commit to
23     my $CVSREP="webpac";
24    
25     # svnroot directory
26     my $SVNROOT="file://$HOME/private/svn/webpac/";
27     # name of respository
28     my $SVNREP="trunk";
29    
30     my $TMPDIR=tempdir( "/tmp/checkoutXXXXX", CLEANUP => 1 );
31    
32     chdir($TMPDIR) || die "can't cd to $TMPDIR: $!";
33    
34     # cvs command with root
35     my $cvs="cvs -d $CVSROOT";
36    
37     #
38     # sub to do logging and system calls
39     #
40     sub log_system($$) {
41     my ($cmd,$errmsg) = @_;
42     print STDERR "## $cmd\n";
43     system $cmd || die "$errmsg: $!";
44     }
45    
46    
47     # ok, now do the checkout
48    
49     log_system("$cvs checkout $CVSREP","cvs checkout failed");
50    
51     # check if svnrev exists
52    
53     if (! -e "$CVSREP/.svnrev") {
54     print <<_USAGE_;
55    
56     Your CVS repository doesn't have $TMPDIR/$CVSREP/.svnrev file!
57    
58     This file is used to commit changes to CVS repository with correct
59     logs from Subversion.
60    
61     Please create .svnrec file with currect svn revision which
62     corresponds to version of checkouted tree and commit that file
63     to CVS repository, e.g.
64    
65     echo 233 > .svnrev
66     cvs add .svnrev
67     cvs commit -m "subversion repository revision sync file" .svnrev
68    
69     _USAGE_
70     print "CVS Repository left in $TMPDIR/$CVSREP\n";
71     exit 1;
72     }
73    
74    
75     open(SVNREV,"$CVSREP/.svnrev") || die "can't open $TMPDIR/$CVSREP/.svnrev: $!";
76     my $rev = <SVNREV>;
77     chomp($rev);
78     close(SVNREV);
79    
80     print "Starting after revision $rev\n";
81    
82    
83     #
84     # sub to commit .svn rev file later
85     #
86    
87     sub commit_svnrev($) {
88     my $rev = shift @_ || die "commit_svnrev needs revision";
89    
90     open(SVNREV,"> $CVSREP/.svnrev") || die "can't open $TMPDIR/$CVSREP/.svnrev: $!";
91     print SVNREV $rev;
92     close(SVNREV);
93    
94     my $msg="subversion revision $rev commited to CVS";
95     my $path=".svnrev";
96     print "$msg\n";
97     system "$cvs commit -m \"$msg\" $CVSREP/$path" || die "cvs commit of $path failed: $!";
98     }
99    
100     #
101     # FIXME!! HEAD should really be next verison and loop because this way we
102     # loose multiple edits of same file and corresponding messages. On the
103     # other hand, if you want to compress your traffic to CVS server and don't
104     # case much about accuracy and completnes of logs there, this might
105     # be good. YMMV
106     #
107     open(LOG, "svn log -r $rev:HEAD -v --xml $SVNROOT/$SVNREP |") || die "svn log for repository $SVNROOT/$SVNREP failed: $!";
108     my $log;
109     while(<LOG>) {
110     $log .= $_;
111     }
112     close(LOG);
113    
114     my $xml = XMLin($log, ForceArray => [ 'path' ]);
115    
116    
117     =begin log_example
118    
119     ------------------------------------------------------------------------
120     r256 | dpavlin | 2004-03-09 13:18:17 +0100 (Tue, 09 Mar 2004) | 2 lines
121    
122     ported r254 from hidra branch
123    
124     =cut
125    
126     my $fmt = "\n" . "-" x 79 . "\nr%5s| %8s | %s\n\n%s\n";
127    
128     foreach my $e (@{$xml->{'logentry'}}) {
129     die "BUG: revision from .svnrev ($rev) greater than from subversion (".$e->{'revision'}.")" if ($rev > $e->{'revision'});
130     $rev = $e->{'revision'};
131     log_system("svn export --force -q -r $rev $SVNROOT/$SVNREP $CVSREP", "svn export of revision $rev failed");
132    
133     printf($fmt, $e->{'revision'}, $e->{'author'}, $e->{'date'}, $e->{'msg'});
134     foreach my $p (@{$e->{'paths'}->{'path'}}) {
135     my ($action,$path) = ($p->{'action'},$p->{'content'});
136    
137     print "svn2cvs: $action $path\n";
138    
139     # prepare path and message
140     my $file = $path;
141     $path =~ s,^/$SVNREP/*,, || die "BUG: can't strip SVNREP from path";
142     my $msg = $e->{'msg'};
143     $msg =~ s/"/\\"/g; # quote "
144    
145     if ($action =~ /M/) {
146     print "svn2cvs: modify $path -- nop\n";
147     } elsif ($action =~ /A/) {
148     log_system("$cvs add -m \"$msg\" $CVSREP/$path", "cvs add of $path failed");
149     } elsif ($action =~ /D/) {
150     log_system("$cvs delete -m \"$msg\" $CVSREP/$path", "cvs delete of $path failed");
151     } else {
152     print "WARNING: action $action not implemented on $path. Bug or missing feature of $0\n";
153     }
154    
155     # now commit changes
156     log_system("$cvs commit -m \"$msg\" $CVSREP/$path", "cvs commit of $path failed");
157    
158     }
159    
160     commit_svnrev($rev);
161     }
162    
163     __END__
164    
165     svn export --force "$SVNROOT/$SVNREP" "$CVSREP"
166    
167     cd dotfiles
168    
169     for file in $(find -type f -not -path \*CVS\*); do
170     FILE=$(basename $file)
171     DIR=$(dirname $file)
172     if ! grep -q "^/$FILE/" $DIR/CVS/Entries ; then
173     cvs add $file
174     fi
175     done
176    
177     #cvs commit -m "Automatic commit from SVN"
178    
179     #rm -rf $TMPDIR
180    
181     echo "cvs left in $TMPDIR"

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26