/[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 2 - (hide annotations)
Tue Mar 9 21:02:42 2004 UTC (20 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 4775 byte(s)
start after current revision

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 dpavlin 2 $rev++;
82 dpavlin 1
83    
84     #
85     # sub to commit .svn rev file later
86     #
87    
88     sub commit_svnrev($) {
89     my $rev = shift @_ || die "commit_svnrev needs revision";
90    
91     open(SVNREV,"> $CVSREP/.svnrev") || die "can't open $TMPDIR/$CVSREP/.svnrev: $!";
92     print SVNREV $rev;
93     close(SVNREV);
94    
95     my $msg="subversion revision $rev commited to CVS";
96     my $path=".svnrev";
97     print "$msg\n";
98     system "$cvs commit -m \"$msg\" $CVSREP/$path" || die "cvs commit of $path failed: $!";
99     }
100    
101     #
102     # FIXME!! HEAD should really be next verison and loop because this way we
103     # loose multiple edits of same file and corresponding messages. On the
104     # other hand, if you want to compress your traffic to CVS server and don't
105     # case much about accuracy and completnes of logs there, this might
106     # be good. YMMV
107     #
108     open(LOG, "svn log -r $rev:HEAD -v --xml $SVNROOT/$SVNREP |") || die "svn log for repository $SVNROOT/$SVNREP failed: $!";
109     my $log;
110     while(<LOG>) {
111     $log .= $_;
112     }
113     close(LOG);
114    
115 dpavlin 2 my $xml = XMLin($log, ForceArray => [ 'logentry', 'path' ]);
116 dpavlin 1
117    
118     =begin log_example
119    
120     ------------------------------------------------------------------------
121     r256 | dpavlin | 2004-03-09 13:18:17 +0100 (Tue, 09 Mar 2004) | 2 lines
122    
123     ported r254 from hidra branch
124    
125     =cut
126    
127     my $fmt = "\n" . "-" x 79 . "\nr%5s| %8s | %s\n\n%s\n";
128    
129 dpavlin 2 if (! $xml->{'logentry'}) {
130     print "no newer log entries in SubVersion repostory. CVS is current\n";
131     exit 0;
132     }
133    
134     print Dumper($xml);
135    
136 dpavlin 1 foreach my $e (@{$xml->{'logentry'}}) {
137     die "BUG: revision from .svnrev ($rev) greater than from subversion (".$e->{'revision'}.")" if ($rev > $e->{'revision'});
138     $rev = $e->{'revision'};
139     log_system("svn export --force -q -r $rev $SVNROOT/$SVNREP $CVSREP", "svn export of revision $rev failed");
140    
141     printf($fmt, $e->{'revision'}, $e->{'author'}, $e->{'date'}, $e->{'msg'});
142     foreach my $p (@{$e->{'paths'}->{'path'}}) {
143     my ($action,$path) = ($p->{'action'},$p->{'content'});
144    
145     print "svn2cvs: $action $path\n";
146    
147     # prepare path and message
148     my $file = $path;
149     $path =~ s,^/$SVNREP/*,, || die "BUG: can't strip SVNREP from path";
150     my $msg = $e->{'msg'};
151     $msg =~ s/"/\\"/g; # quote "
152    
153     if ($action =~ /M/) {
154     print "svn2cvs: modify $path -- nop\n";
155     } elsif ($action =~ /A/) {
156     log_system("$cvs add -m \"$msg\" $CVSREP/$path", "cvs add of $path failed");
157     } elsif ($action =~ /D/) {
158     log_system("$cvs delete -m \"$msg\" $CVSREP/$path", "cvs delete of $path failed");
159     } else {
160     print "WARNING: action $action not implemented on $path. Bug or missing feature of $0\n";
161     }
162    
163     # now commit changes
164     log_system("$cvs commit -m \"$msg\" $CVSREP/$path", "cvs commit of $path failed");
165    
166     }
167    
168     commit_svnrev($rev);
169     }
170    
171     __END__
172    
173     svn export --force "$SVNROOT/$SVNREP" "$CVSREP"
174    
175     cd dotfiles
176    
177     for file in $(find -type f -not -path \*CVS\*); do
178     FILE=$(basename $file)
179     DIR=$(dirname $file)
180     if ! grep -q "^/$FILE/" $DIR/CVS/Entries ; then
181     cvs add $file
182     fi
183     done
184    
185     #cvs commit -m "Automatic commit from SVN"
186    
187     #rm -rf $TMPDIR
188    
189     echo "cvs left in $TMPDIR"

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26