/[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 23 by dpavlin, Tue Jan 3 00:03:22 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 237  foreach my $e (@{$xml->{'logentry'}}) { Line 267  foreach my $e (@{$xml->{'logentry'}}) {
267          foreach my $p (@{$e->{'paths'}->{'path'}}) {          foreach my $p (@{$e->{'paths'}->{'path'}}) {
268                  my ($action,$path) = ($p->{'action'},$p->{'content'});                  my ($action,$path) = ($p->{'action'},$p->{'content'});
269    
270                    next if ($path =~ m#/\.svnrev$#);
271    
272                  print "svn2cvs: $action $path\n";                  print "svn2cvs: $action $path\n";
273    
274                  # prepare path and message                  # prepare path and message
275                  my $file = $path;                  my $file = $path;
276                  $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";
277    
278                  if (! $path) {                  if (! $path) {
279                          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 287  foreach my $e (@{$xml->{'logentry'}}) {
287                          print "svn2cvs: modify $path -- nop\n";                          print "svn2cvs: modify $path -- nop\n";
288                  } elsif ($action =~ /A/) {                  } elsif ($action =~ /A/) {
289                          if (-d $path) {                          if (-d $path) {
290                                  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: $!";  
291                          } elsif ($path =~ m,^(.+)/[^/]+$, && ! -e "$1/CVS/Root") {                          } elsif ($path =~ m,^(.+)/[^/]+$, && ! -e "$1/CVS/Root") {
292                                  my $dir = $1;                                  my $dir = $1;
293                                  in_entries($dir) || log_system("$cvs add $dir", "cvs add of dir $dir failed");                                  in_entries($dir) || add_dir($dir, $msg);
294                                  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");
295                          } else {                          } else {
296                                  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");
297                          }                          }
298                  } elsif ($action =~ /D/) {                  } elsif ($action =~ /D/) {
299                          unlink $path || die "can't delete $path: $!";                          if (-e $path) {
300                          log_system("$cvs delete $path", "cvs delete of $path failed");                                  unlink $path || die "can't delete $path: $!";
301                                    log_system("$cvs delete $path", "cvs delete of $path failed");
302                            } else {
303                                    print "WARNING: $path is not present, skipping...\n";
304                                    undef $path;
305                            }
306                  } else {                  } else {
307                          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";
308                  }                  }
309    
310                  # save commits for later                  # save commits for later
311                  push @commit, $path;                  push @commit, $path if ($path);
312    
313          }          }
314    
# Line 293  foreach my $e (@{$xml->{'logentry'}}) { Line 321  foreach my $e (@{$xml->{'logentry'}}) {
321          commit_svnrev($rev);          commit_svnrev($rev);
322  }  }
323    
324    # cd out of $CVSREP before File::Temp::END is called
325    chdir("/tmp") || die "can't cd to /tmp: $!";
326    
327  __END__  __END__
328    
329  =pod  =pod
# Line 408  Documentation improvements and other sma Line 439  Documentation improvements and other sma
439    
440  Fixed path deduction (overlap between Subversion reporistory and CVS checkout).  Fixed path deduction (overlap between Subversion reporistory and CVS checkout).
441    
442    =item r21
443    
444    Use C<update -d> instead of checkout after import.
445    Added fixes by Paul Egan <paulegan@mail.com> for XMLin and fixing working
446    directory.
447    
448    =item r22
449    
450    Rewritten import from revision 0 to empty repository, better importing
451    of deep directory structures, initial support for recovery from partial
452    commit.
453    
454  =back  =back
455    
456  =head1 AUTHOR  =head1 AUTHOR

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

  ViewVC Help
Powered by ViewVC 1.1.26