Skip to content

Instantly share code, notes, and snippets.

@eserte
Last active April 26, 2019 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eserte/1a6994f0da352ef1ea9bc3398e347846 to your computer and use it in GitHub Desktop.
Save eserte/1a6994f0da352ef1ea9bc3398e347846 to your computer and use it in GitHub Desktop.
rcs2git
#!/usr/bin/perl -w
# -*- perl -*-
#
# $Id: rcs2cvsrepo.pl,v 1.3 2008/12/31 13:52:17 eserte Exp eserte $
# Author: Slaven Rezic
#
# Copyright (C) 2008 Slaven Rezic. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
# Mail: slaven@rezic.de
# WWW: http://www.rezic.de/eserte/
#
# Turns RCS-controlled files in the current directory into an CVS
# repository.
# TODO: there's no way to deal with deleted RCS files. Maybe some
# automatic Attic creation?
use strict;
use File::Copy qw(cp);
use File::Find qw();
use File::Path qw(mkpath);
use Getopt::Long;
# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
my $f;
GetOptions("f" => \$f) or die "usage!";
my $destdir = shift or die "Please specify destination directory";
if (-e $destdir) {
if (!$f) {
die "$destdir must not exist";
}
} else {
mkdir $destdir or die "Cannot create $destdir: $!";
}
sub wanted;
# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, '.');
exit;
sub wanted {
/^RCS\z/s and do {
(my $path = $File::Find::name) =~ s{^\./}{};
$path =~ s{RCS$}{};
warn "mkdir $destdir/$path ...\n";
if (!-d "$destdir/$path") {
mkpath "$destdir/$path"
or die "While creating $destdir/$path: $!";
}
for my $file (glob("RCS/*")) {
warn "cp $file $destdir/$path ...\n";
cp $file, "$destdir/$path"
or die "While copying $file to $destdir/$path: $!";
}
};
}
__END__
#!/usr/bin/perl -w
# -*- perl -*-
#
# Author: Slaven Rezic
#
# Copyright (C) 2010 Slaven Rezic. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
# Mail: slaven@rezic.de
# WWW: http://www.rezic.de/eserte/
#
use strict;
use FindBin;
use Cwd qw(cwd);
use File::Basename qw(basename);
use File::Path qw(mkpath);
use File::Temp qw(tempfile tempdir);
use Getopt::Long;
sub mymkpath ($);
sub myrcs2cvsrepo ($$);
sub mylocalcvsimport ($$);
my $n = 1;
GetOptions("doit!" => sub { $n = 0 })
or die "usage: $0 [-doit] srcdir";
my $srcdir = shift or die "RCS-controlled directory to convert?";
-d $srcdir or die "$srcdir is not a directory";
my $project = basename $srcdir;
# XXX duplicated in my-git-migration.pl
my($A_fh, $A_file) = tempfile(UNLINK => 1);
print $A_fh <<'EOF';
eserte=Slaven Rezic <slaven@rezic.de>
EOF
close $A_fh
or die $!;
my($cvsdir) = tempdir("cvs-XXXXXXXX", CLEANUP => 1, TMPDIR => 1)
or die "Can't create temporary directory: $!";
mymkpath "$cvsdir/$project";
mymkpath "$cvsdir/CVSROOT";
myrcs2cvsrepo($srcdir, "$cvsdir/$project");
my($gitdir) = tempdir("git-XXXXXXXX", CLEANUP => 0, TMPDIR => 1)
or die "Can't create temporary directory: $!";
mylocalcvsimport($cvsdir, $gitdir);
if ($n) {
rmdir $gitdir;
} else {
print STDERR "NOTE: git directory is in: $gitdir\n";
}
if ($n) {
print STDERR "Now run the command with -doit switch\n";
}
END { chdir "/" } # for File::Temp
sub mymkpath ($) {
my($path) = @_;
if (!-d $path) {
if ($n) {
warn "Would create directory $path.\n";
} else {
mkpath $path;
die "Can't create $path: $!" if !-d $path;
}
}
}
sub myrcs2cvsrepo ($$) {
my($src, $dest) = @_;
chdir $src
or die "Cannot chdir to $src: $!";
my @cmd = ("$FindBin::RealBin/rcs2cvsrepo.pl", "-f", $dest);
_anycmd(@cmd);
}
sub mylocalcvsimport ($$) {
my($src, $dest) = @_;
mymkpath $dest;
chdir $dest
or die "Can't chdir to $dest: $!";
my @cmd = ("git", "cvsimport", "-A", $A_file, "-v", "-d", $src, $project);
_anycmd(@cmd);
}
sub _anycmd {
my(@cmd) = @_;
if ($n) {
warn "Would run <@cmd> in directory <" . cwd . ">\n";
} else {
system @cmd;
if ($? != 0) {
die "Command <@cmd> failed with $?";
}
}
}
__END__
Contains a hack to convert RCS to git using CVS as an intermediate
HOWTO:
- make sure that "git cvsimport" works (e.g. by installing the Debian package git-cvs)
- hack the contents of $A_file in rcs2git.pl --- this should have a mapping of username to fullname <email>
- run "./rcs2git.pl /path/to/directory-containing-RCS" --- this is just a dry run
- run the same command with "--doit" --- this will do the real thing
- the generated git directory will be located in /tmp; see last diagnostic line"
@eserte
Copy link
Author

eserte commented Apr 26, 2019

@andk: please try out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment