/[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

Diff of /trunk/svn2cvs.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 20 by dpavlin, Mon Apr 18 16:43:08 2005 UTC revision 26 by dpavlin, Sun Jul 30 18:45:51 2006 UTC
# Line 13  Line 13 
13    
14  use strict;  use strict;
15  use File::Temp qw/ tempdir /;  use File::Temp qw/ tempdir /;
16    use File::Path;
17  use Data::Dumper;  use Data::Dumper;
18  use XML::Simple;  use XML::Simple;
19    
# Line 28  if ($SVNROOT !~ m,^[\w+]+:///*\w+,) { Line 29  if ($SVNROOT !~ m,^[\w+]+:///*\w+,) {
29          exit 1;          exit 1;
30  }  }
31    
32    # Ensure File::Temp::END can clean up:
33    $SIG{__DIE__} = sub { chdir("/tmp"); die @_ };
34    
35  my $TMPDIR=tempdir( "/tmp/checkoutXXXXX", CLEANUP => 1 );  my $TMPDIR=tempdir( "/tmp/checkoutXXXXX", CLEANUP => 1 );
36    
37  chdir($TMPDIR) || die "can't cd to $TMPDIR: $!";  sub cd_tmp {
38            chdir($TMPDIR) || die "can't cd to $TMPDIR: $!";
39    }
40    
41    sub cd_rep {
42            chdir("$TMPDIR/$CVSREP") || die "can't cd to $TMPDIR/$CVSREP: $!";
43    }
44    
45    print "## using TMPDIR $TMPDIR\n";
46    
47  # cvs command with root  # cvs command with root
48  my $cvs="cvs -d $CVSROOT";  my $cvs="cvs -d $CVSROOT";
49    
50    # current revision in CVS
51    my $rev;
52    
53  #  #
54  # sub to do logging and system calls  # sub to do logging and system calls
55  #  #
# Line 68  sub commit_svnrev { Line 83  sub commit_svnrev {
83          }          }
84  }  }
85    
86  # current revision in CVS  sub add_dir($$) {
87  my $rev;          my ($path,$msg) = @_;
88            print "# add_dir($path)\n";
89            die "add_dir($path) is not directory" unless (-d $path);
90    
91            my $curr_dir;
92    
93            foreach my $d (split(m#/#, $path)) {
94                    $curr_dir .= ( $curr_dir ? '/' : '') . $d;
95    
96                    next if in_entries($curr_dir);
97                    next if (-e "$curr_dir/CVS");
98    
99                    log_system("$cvs add $curr_dir", "cvs add of $curr_dir failed");
100            }
101    }
102    
103  # ok, now do the checkout  # ok, now do the checkout
104  eval {  eval {
105            cd_tmp;
106          log_system("$cvs -q checkout $CVSREP", "cvs checkout failed");          log_system("$cvs -q checkout $CVSREP", "cvs checkout failed");
107  };  };
108    
# Line 88  _NEW_REP_ Line 118  _NEW_REP_
118    
119          print "start import of new module [yes]: ";          print "start import of new module [yes]: ";
120          my $in = <STDIN>;          my $in = <STDIN>;
121            cd_tmp;
122          mkdir($CVSREP) || die "can't create $CVSREP: $!";          mkdir($CVSREP) || die "can't create $CVSREP: $!";
123            cd_rep;
         chdir($CVSREP) || die "can't cd to $TMPDIR/$CVSREP: $!";  
124    
125          open(SVNREV,"> .svnrev") || die "can't open $CVSREP/.svnrev: $!";          open(SVNREV,"> .svnrev") || die "can't open $CVSREP/.svnrev: $!";
126          print SVNREV "0";          print SVNREV "0";
# Line 99  _NEW_REP_ Line 129  _NEW_REP_
129          $rev = 0;          $rev = 0;
130    
131          # create new module          # create new module
132          log_system("$cvs import -m 'new CVS module' $CVSREP svn2cvs r0", "can't import new module into $CVSREP");          cd_rep;
133            log_system("$cvs import -d -m 'new CVS module' $CVSREP svn r$rev", "import of new repository");
134          unlink ".svnrev" || die "can't remove .svnrev: $!";          cd_tmp;
135          chdir($TMPDIR) || die "can't cd to $TMPDIR: $!";          rmtree($CVSREP) || die "can't remove $CVSREP";
         rmdir $CVSREP || die "can't remove $CVSREP: $!";  
   
         # and checkout it  
136          log_system("$cvs -q checkout $CVSREP", "cvs checkout failed");          log_system("$cvs -q checkout $CVSREP", "cvs checkout failed");
137            cd_rep;
         chdir($CVSREP) || die "can't cd to $TMPDIR/$CVSREP: $!";  
138    
139  } else {  } else {
   
140          # import into existing module directory in CVS          # import into existing module directory in CVS
141    
142          chdir($CVSREP) || die "can't cd to $TMPDIR/$CVSREP: $!";          cd_rep;
   
   
143          # check if svnrev exists          # check if svnrev exists
144          if (! -e ".svnrev") {          if (! -e ".svnrev") {
145                  print <<_USAGE_;                  print <<_USAGE_;
# Line 173  while(<LOG>) { Line 196  while(<LOG>) {
196  }  }
197  close(LOG);  close(LOG);
198    
199  my $xml = XMLin($log, ForceArray => [ 'logentry', 'path' ]);  
200    my $xml;
201    eval {
202            $xml = XMLin($log, ForceArray => [ 'logentry', 'path' ]);
203    };
204    
205    
206  #=begin log_example  #=begin log_example
# Line 202  sub in_entries($) { Line 229  sub in_entries($) {
229                  if ($d !~ m,/$, && $d ne "") {                  if ($d !~ m,/$, && $d ne "") {
230                          $d .= "/";                          $d .= "/";
231                  }                  }
232                  open(E, $d."CVS/Entries") || die "can't open ${d}CVS/Entries: $!";                  open(E, $d."CVS/Entries") || return 0;
233                  while(<E>) {                  while(<E>) {
234                          return(1) if (m,^/$f/,);                          return(1) if (m,^/$f/,);
235                  }                  }
# Line 211  sub in_entries($) { Line 238  sub in_entries($) {
238          }          }
239  }  }
240    
241    cd_tmp;
242    cd_rep;
243    
244  foreach my $e (@{$xml->{'logentry'}}) {  foreach my $e (@{$xml->{'logentry'}}) {
245          die "BUG: revision from .svnrev ($rev) greater than from subversion (".$e->{'revision'}.")" if ($rev > $e->{'revision'});          die "BUG: revision from .svnrev ($rev) greater than from subversion (".$e->{'revision'}.")" if ($rev > $e->{'revision'});
246          $rev = $e->{'revision'};          $rev = $e->{'revision'};
# Line 223  foreach my $e (@{$xml->{'logentry'}}) { Line 253  foreach my $e (@{$xml->{'logentry'}}) {
253          do {          do {
254                  if ($tmpsvn =~ s#(/[^/]+)/*$##) {                  if ($tmpsvn =~ s#(/[^/]+)/*$##) {
255                          $SVNREP = $1 . $SVNREP;                          $SVNREP = $1 . $SVNREP;
256                    } elsif ($e->{'paths'}->{'path'}->[0]->{'copyfrom-path'}) {
257                            print "NOTICE: copyfrom outside synced repository ignored - skipping\n";
258                            next;
259                  } else {                  } else {
260                          print "NOTICE: can't deduce svn dir from $SVNROOT - skipping\n";                          print "NOTICE: can't deduce svn dir from $SVNROOT - skipping\n";
261                          next;                          next;
# Line 237  foreach my $e (@{$xml->{'logentry'}}) { Line 270  foreach my $e (@{$xml->{'logentry'}}) {
270          foreach my $p (@{$e->{'paths'}->{'path'}}) {          foreach my $p (@{$e->{'paths'}->{'path'}}) {
271                  my ($action,$path) = ($p->{'action'},$p->{'content'});                  my ($action,$path) = ($p->{'action'},$p->{'content'});
272    
273                    next if ($path =~ m#/\.svnrev$#);
274    
275                  print "svn2cvs: $action $path\n";                  print "svn2cvs: $action $path\n";
276    
277                  # prepare path and message                  # prepare path and message
278                  my $file = $path;                  my $file = $path;
279                  $path =~ s,^$SVNREP/*,, || die "BUG: can't strip SVNREP '$SVNREP' from path";                  $path =~ s#^\Q$SVNREP\E/*## || die "BUG: can't strip SVNREP '$SVNREP' from path";
280    
281                  if (! $path) {                  if (! $path) {
282                          print "NOTICE: skipped this operation. Probably trunk creation\n";                          print "NOTICE: skipped this operation. Probably trunk creation\n";
# Line 255  foreach my $e (@{$xml->{'logentry'}}) { Line 290  foreach my $e (@{$xml->{'logentry'}}) {
290                          print "svn2cvs: modify $path -- nop\n";                          print "svn2cvs: modify $path -- nop\n";
291                  } elsif ($action =~ /A/) {                  } elsif ($action =~ /A/) {
292                          if (-d $path) {                          if (-d $path) {
293                                  chdir($path) || die "can't cd into dir $path for import: $!";                                  add_dir($path, $msg);
                                 log_system("$cvs import -d -m '$msg' $CVSREP/$path svn r$rev", "cvs import of $path failed");  
                                 if (-d "$CVSREP/$path") {  
                                         rmdir "$CVSREP/$path" || die "can't remove $CVSREP/$path: $!";  
                                 } else {  
                                         unlink "$CVSREP/$path" || die "can't remove $CVSREP/$path: $!";  
                                 }  
                                 chdir("$TMPDIR") || die "can't cd to $TMPDIR/$CVSREP: $!";  
                                 log_system("$cvs checkout $CVSREP/$path", "cvs checkout of imported dir $path failed");  
                                 chdir("$TMPDIR/$CVSREP") || die "can't cd back to $TMPDIR/$CVSREP: $!";  
294                          } elsif ($path =~ m,^(.+)/[^/]+$, && ! -e "$1/CVS/Root") {                          } elsif ($path =~ m,^(.+)/[^/]+$, && ! -e "$1/CVS/Root") {
295                                  my $dir = $1;                                  my $dir = $1;
296                                  in_entries($dir) || log_system("$cvs add $dir", "cvs add of dir $dir failed");                                  in_entries($dir) || add_dir($dir, $msg);
297                                  in_entries($path) || log_system("$cvs add $path", "cvs add of $path failed");                                  in_entries($path) || log_system("$cvs add $path", "cvs add of $path failed");
298                          } else {                          } else {
299                                  in_entries($path) || log_system("$cvs add $path", "cvs add of $path failed");                                  in_entries($path) || log_system("$cvs add $path", "cvs add of $path failed");
300                          }                          }
301                  } elsif ($action =~ /D/) {                  } elsif ($action =~ /D/) {
302                          unlink $path || die "can't delete $path: $!";                          if (-e $path) {
303                          log_system("$cvs delete $path", "cvs delete of $path failed");                                  unlink $path || die "can't delete $path: $!";
304                                    log_system("$cvs delete $path", "cvs delete of $path failed");
305                            } else {
306                                    print "WARNING: $path is not present, skipping...\n";
307                                    undef $path;
308                            }
309                  } else {                  } else {
310                          print "WARNING: action $action not implemented on $path. Bug or missing feature of $0\n";                          print "WARNING: action $action not implemented on $path. Bug or missing feature of $0\n";
311                  }                  }
312    
313                  # save commits for later                  # save commits for later
314                  push @commit, $path;                  push @commit, $path if ($path);
315    
316          }          }
317    
# Line 293  foreach my $e (@{$xml->{'logentry'}}) { Line 324  foreach my $e (@{$xml->{'logentry'}}) {
324          commit_svnrev($rev);          commit_svnrev($rev);
325  }  }
326    
327    # cd out of $CVSREP before File::Temp::END is called
328    chdir("/tmp") || die "can't cd to /tmp: $!";
329    
330  __END__  __END__
331    
332  =pod  =pod
# Line 408  Documentation improvements and other sma Line 442  Documentation improvements and other sma
442    
443  Fixed path deduction (overlap between Subversion reporistory and CVS checkout).  Fixed path deduction (overlap between Subversion reporistory and CVS checkout).
444    
445    =item r21
446    
447    Use C<update -d> instead of checkout after import.
448    Added fixes by Paul Egan <paulegan@mail.com> for XMLin and fixing working
449    directory.
450    
451    =item r22
452    
453    Rewritten import from revision 0 to empty repository, better importing
454    of deep directory structures, initial support for recovery from partial
455    commit.
456    
457  =back  =back
458    
459  =head1 AUTHOR  =head1 AUTHOR

Legend:
Removed from v.20  
changed lines
  Added in v.26

  ViewVC Help
Powered by ViewVC 1.1.26