/[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 26 by dpavlin, Sun Jul 30 18:45:51 2006 UTC revision 35 by dpavlin, Fri Sep 7 16:39:42 2007 UTC
# Line 17  use File::Path; Line 17  use File::Path;
17  use Data::Dumper;  use Data::Dumper;
18  use XML::Simple;  use XML::Simple;
19    
20    # do we want to sync just part of repository?
21    my $partial_import = 1;
22    
23  if (@ARGV < 2) {  if (@ARGV < 2) {
24          print "usage: $0 SVN_URL CVSROOT CVSREPOSITORY\n";          print "usage: $0 SVN_URL CVSROOT CVSREPOSITORY\n";
25          exit 1;          exit 1;
# Line 45  sub cd_rep { Line 48  sub cd_rep {
48  print "## using TMPDIR $TMPDIR\n";  print "## using TMPDIR $TMPDIR\n";
49    
50  # cvs command with root  # cvs command with root
51  my $cvs="cvs -d $CVSROOT";  my $cvs="cvs -f -d $CVSROOT";
52    
53  # current revision in CVS  # current revision in CVS
54  my $rev;  my $rev;
# Line 75  sub commit_svnrev { Line 78  sub commit_svnrev {
78          my $path=".svnrev";          my $path=".svnrev";
79    
80          if ($add_new) {          if ($add_new) {
81                  system "$cvs add $path" || die "cvs add of $path failed: $!";                  system "$cvs add '$path'" || die "cvs add of $path failed: $!";
82          } else {          } else {
83                  my $msg="subversion revision $rev commited to CVS";                  my $msg="subversion revision $rev commited to CVS";
84                  print "$msg\n";                  print "$msg\n";
85                  system "$cvs commit -m '$msg' $path" || die "cvs commit of $path failed: $!";                  system "$cvs commit -m '$msg' '$path'" || die "cvs commit of $path failed: $!";
86          }          }
87  }  }
88    
# Line 96  sub add_dir($$) { Line 99  sub add_dir($$) {
99                  next if in_entries($curr_dir);                  next if in_entries($curr_dir);
100                  next if (-e "$curr_dir/CVS");                  next if (-e "$curr_dir/CVS");
101    
102                  log_system("$cvs add $curr_dir", "cvs add of $curr_dir failed");                  log_system("$cvs add '$curr_dir'", "cvs add of $curr_dir failed");
103          }          }
104  }  }
105    
# Line 219  if (! $xml->{'logentry'}) { Line 222  if (! $xml->{'logentry'}) {
222          exit 0;          exit 0;
223  }  }
224    
225  # check if file exists in CVS/Entries  # my ($dir,$file) = dir_file($path);
226  sub in_entries($) {  sub dir_file($) {
227          my $path = shift;          my $path = shift;
228          if ($path !~ m,^(.*?/*)([^/]+)$,) {          if ($path !~ m,^(.*?/*)([^/]+)$,) {
229                  die "can't split '$path' to dir and file!";                  die "can't split '$path' to dir and file!";
# Line 229  sub in_entries($) { Line 232  sub in_entries($) {
232                  if ($d !~ m,/$, && $d ne "") {                  if ($d !~ m,/$, && $d ne "") {
233                          $d .= "/";                          $d .= "/";
234                  }                  }
235                  open(E, $d."CVS/Entries") || return 0;                  return ($d,$f);
236                  while(<E>) {          }
237                          return(1) if (m,^/$f/,);  }
238    
239    # return all files in CVS/Entries
240    sub entries($) {
241            my $dir = shift;
242            die "entries expects directory argument!" unless -d $dir;
243            my @entries;
244            open(my $fh, "$dir/CVS/Entries") || return 0;
245            while(<$fh>) {
246                    if ( m{^D/([^/]+)}, ) {
247                            my $sub_dir = $1;
248                            warn "#### entries recurse into: $dir/$sub_dir";
249                            push @entries, map { "$sub_dir/$_" } entries("$dir/$sub_dir");
250                            push @entries, $sub_dir;
251                    } elsif ( m{^/([^/]+)/} ) {
252                            push @entries, $1;
253                    } elsif ( ! m{^D$} ) {
254                            die "can't decode entries line: $_";
255                  }                  }
                 close(E);  
                 return 0;  
256          }          }
257            close($fh);
258            warn "#### entries($dir) => ",join("|",@entries);
259            return @entries;
260    }
261    
262    # check if file exists in CVS/Entries
263    sub in_entries($) {
264            my $path = shift;
265            my ($dir,$file) = dir_file($path);
266            open(E, "$dir/CVS/Entries") || return 0;
267            while(<E>) {
268                    return(1) if (m,^/$file/,);
269            }
270            close(E);
271            return 0;
272  }  }
273    
274  cd_tmp;  cd_tmp;
# Line 251  foreach my $e (@{$xml->{'logentry'}}) { Line 284  foreach my $e (@{$xml->{'logentry'}}) {
284          my $tmpsvn = $SVNROOT || die "BUG: SVNROOT empty!";          my $tmpsvn = $SVNROOT || die "BUG: SVNROOT empty!";
285          my $tmppath = $e->{'paths'}->{'path'}->[0]->{'content'} || die "BUG: tmppath empty!";          my $tmppath = $e->{'paths'}->{'path'}->[0]->{'content'} || die "BUG: tmppath empty!";
286          do {          do {
287                  if ($tmpsvn =~ s#(/[^/]+)/*$##) {                  if ($tmpsvn =~ s#(/[^/]+)/*$##) {       # vim fix
288                          $SVNREP = $1 . $SVNREP;                          $SVNREP = $1 . $SVNREP;
289                  } elsif ($e->{'paths'}->{'path'}->[0]->{'copyfrom-path'}) {                  } elsif ($e->{'paths'}->{'path'}->[0]->{'copyfrom-path'}) {
290                          print "NOTICE: copyfrom outside synced repository ignored - skipping\n";                          print "NOTICE: copyfrom outside synced repository ignored - skipping\n";
# Line 267  foreach my $e (@{$xml->{'logentry'}}) { Line 300  foreach my $e (@{$xml->{'logentry'}}) {
300          printf($fmt, $e->{'revision'}, $e->{'author'}, $e->{'date'}, $e->{'msg'});          printf($fmt, $e->{'revision'}, $e->{'author'}, $e->{'date'}, $e->{'msg'});
301          my @commit;          my @commit;
302    
303            my $msg = $e->{'msg'};
304            $msg =~ s/'/'\\''/g;    # quote "
305    
306            sub cvs_commit {
307                    my $msg = shift || die "no msg?";
308                    if ( ! @_ ) {
309                            warn "commit ignored, no files\n";
310                            return;
311                    }
312                    log_system("$cvs commit -m '$msg' '".join("' '",@_)."'", "cvs commit of ".join(",",@_)." failed");
313            }
314    
315          foreach my $p (@{$e->{'paths'}->{'path'}}) {          foreach my $p (@{$e->{'paths'}->{'path'}}) {
316                  my ($action,$path) = ($p->{'action'},$p->{'content'});                  my ($action,$path) = ($p->{'action'},$p->{'content'});
317    
# Line 276  foreach my $e (@{$xml->{'logentry'}}) { Line 321  foreach my $e (@{$xml->{'logentry'}}) {
321    
322                  # prepare path and message                  # prepare path and message
323                  my $file = $path;                  my $file = $path;
324                  $path =~ s#^\Q$SVNREP\E/*## || die "BUG: can't strip SVNREP '$SVNREP' from path";                  if ( $path !~ s#^\Q$SVNREP\E/*## ) {
325                            print "NOTICE: skipping '$path' which isn't under repository root '$SVNREP'\n";
326                            die unless $partial_import;
327                            next;
328                    }
329    
330                  if (! $path) {                  if (! $path) {
331                          print "NOTICE: skipped this operation. Probably trunk creation\n";                          print "NOTICE: skipped this operation. Probably trunk creation\n";
# Line 286  foreach my $e (@{$xml->{'logentry'}}) { Line 335  foreach my $e (@{$xml->{'logentry'}}) {
335                  my $msg = $e->{'msg'};                  my $msg = $e->{'msg'};
336                  $msg =~ s/'/'\\''/g;    # quote "                  $msg =~ s/'/'\\''/g;    # quote "
337    
338                  if ($action =~ /M/) {                  sub add_path {
339                          print "svn2cvs: modify $path -- nop\n";                          my $path = shift || die "no path?";
340                  } elsif ($action =~ /A/) {          
341                          if (-d $path) {                          if (-d $path) {
342                                  add_dir($path, $msg);                                  add_dir($path, $msg);
343                          } elsif ($path =~ m,^(.+)/[^/]+$, && ! -e "$1/CVS/Root") {                          } elsif ($path =~ m,^(.+)/[^/]+$, && ! -e "$1/CVS/Root") {
344                                  my $dir = $1;                                  my $dir = $1;
345                                  in_entries($dir) || add_dir($dir, $msg);                                  in_entries($dir) || add_dir($dir, $msg);
346                                  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");
347                          } else {                          } else {
348                                  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");
349                          }                          }
350                    }
351    
352                    if ($action =~ /M/) {
353                            if ( in_entries( $path ) ) {
354                                    print "svn2cvs: modify $path -- nop\n";
355                            } else {
356                                    print "WARNING: modify $path which isn't in CVS, adding...\n";
357                                    add_path($path);
358                            }
359                    } elsif ($action =~ /A/) {
360                            add_path($path);
361                  } elsif ($action =~ /D/) {                  } elsif ($action =~ /D/) {
362                          if (-e $path) {                          if (-e $path) {
363                                  unlink $path || die "can't delete $path: $!";                                  if ( -d $path ) {
364                                  log_system("$cvs delete $path", "cvs delete of $path failed");                                          warn "#### remove directory: $path";
365                                            my @sub_commit;
366                                            foreach my $f ( entries($path) ) {
367                                                    $f = "$path/$f";
368                                            if ( -f $f ) {
369                                                            unlink($f) || die "can't delete file $f: $!";
370    #                                               } else {
371    #                                                       rmtree($f) || die "can't delete dir $f: $!";
372                                                    }
373                                                    log_system("$cvs delete '$f'", "cvs delete of file $f failed");
374                                                    push @sub_commit, $f;
375                                            }
376                                            log_system("$cvs delete '$path'", "cvs delete of file $path failed");
377                                            cvs_commit($msg, @sub_commit, $path);
378                                            log_system("$cvs update -dP '$path'", "cvs update -dP $path failed");
379                                    } else {
380                                            warn "#### remove file: $path";
381                                            unlink($path) || die "can't delete $path: $!";
382                                            log_system("$cvs delete '$path'", "cvs delete of dir $path failed");
383                                    }
384                          } else {                          } else {
385                                  print "WARNING: $path is not present, skipping...\n";                                  print "WARNING: $path is not present, skipping...\n";
386                                  undef $path;                                  undef $path;
# Line 315  foreach my $e (@{$xml->{'logentry'}}) { Line 394  foreach my $e (@{$xml->{'logentry'}}) {
394    
395          }          }
396    
         my $msg = $e->{'msg'};  
         $msg =~ s/'/'\\''/g;    # quote "  
   
397          # now commit changes          # now commit changes
398          log_system("$cvs commit -m '$msg' ".join(" ",@commit), "cvs commit of ".join(",",@commit)." failed");          cvs_commit($msg, @commit);
399    
400          commit_svnrev($rev);          commit_svnrev($rev);
401  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26