#!/pro/bin/perl
my
%sccs_ext
;
my
@sccs
;
find (
sub
{
$File::Find::dir
=~ m{(?:^|/)SCCS$} and m/^s\./ or
return
;
push
@sccs
,
$File::Find::name
;
m/\.(\w+)$/ and
$sccs_ext
{$1}++;
},
glob
"*"
);
@sccs
or
die
"No SCCS source files to convert\n"
;
-d
".git"
and
die
".git already exists\n"
;
system
"git init"
;
sub
pr_date
{
my
@dt
=
localtime
shift
;
sprintf
"%s %02d-%02d-%4d %02d:%02d:%02d"
,
(
qw( Sun Mon Tue Wed Thu Fri Sat )
)[
$dt
[6]],
$dt
[3],
$dt
[4] + 1,
$dt
[5] + 1900,
$dt
[2],
$dt
[1],
$dt
[0];
}
chomp
(
my
$branchname
=
qx(git symbolic-ref HEAD)
);
open
my
$gfi
,
"|-"
,
qw(git fast-import --quiet)
;
my
$mark
;
my
$domain
= Net::Domain::hostdomain () ||
"procura.nl"
;
my
%tzoffset
;
my
$tzoffset
=
sub
{
my
$offset_s
= timegm (
localtime
(
$_
[0])) -
$_
[0];
my
$off
=
abs
$offset_s
/ 60;
my
(
$off_h
,
$off_m
) = (
$off
/ 60,
$off
% 60);
$tzoffset
{
$offset_s
} ||= (
$offset_s
>= 0 ?
"+"
:
"-"
)
.
sprintf
"%02d%02d"
,
$off_h
,
$off_m
;
};
my
%sccs
;
my
%file
;
my
@fail
;
foreach
my
$f
(
sort
@sccs
) {
my
$sccs
;
eval
{
$sccs
= VCS::SCCS->new (
$f
) };
unless
(
$sccs
) {
warn
"Cannot convert $f\n"
;
push
@fail
,
$f
;
next
;
}
$sccs
->set_translate (
"SCCS"
);
my
$fn
=
$sccs
->file ();
$file
{
$fn
}++;
foreach
my
$rm
(@{
$sccs
->revision_map ()}) {
my
(
$rev
,
$vsn
) = @{
$rm
};
my
$delta
=
$sccs
->delta (
$rev
);
$sccs
{
pack
"NA*"
,
$delta
->{stamp},
$fn
} = [
$sccs
,
$rev
, ++
$mark
];
my
$data
=
scalar
$sccs
->body (
$rev
);
print
{
$gfi
}
"blob\nmark :"
,
$mark
,
"\ndata "
,
length
(
$data
),
"\n"
,
$data
,
"\n"
;
printf
STDERR
"%-20s %3d %8s %s\r"
,
$fn
,
$rev
,
$vsn
,
pr_date (
$delta
->{stamp});
}
print
STDERR
"\n"
;
}
foreach
my
$c
(
sort
keys
%sccs
) {
my
(
$sccs
,
$rev
,
$mark
) = @{
$sccs
{
$c
}};
my
$fn
=
$sccs
->file ();
my
%delta
= %{
$sccs
->delta (
$rev
)};
my
$stamp
= pr_date (
$delta
{stamp});
my
$vsn
=
$delta
{version};
printf
STDERR
"%-20s %3d %6s %s %s %s\n"
,
$fn
,
$rev
,
$vsn
,
$stamp
,
$delta
{date},
$delta
{
"time"
};
print
{
$gfi
}
"commit "
,
$branchname
,
"\n"
;
print
{
$gfi
}
"committer "
,
$delta
{committer},
" <"
,
$delta
{committer},
"@"
,
$domain
,
"> "
,
$delta
{stamp},
" "
,
$tzoffset
->(
$delta
{stamp}),
"\n"
;
my
$mr
=
$delta
{mr} ||
""
;
$mr
=~ s/^-$//;
$mr
and
$mr
=
"SCCS-mr: $mr"
;
$vsn
and
$vsn
=
"SCCS-vsn: $vsn"
;
my
$cmnt
=
$delta
{comment} ||
""
;
$cmnt
||=
"(no message)"
;
$cmnt
.=
"\n"
;
my
$msg
=
join
"\n"
,
$cmnt
,
grep
m/\S/,
$mr
,
$vsn
;
print
{
$gfi
}
"data "
,
length
(
$msg
),
"\n$msg\n"
;
my
$mode
=
$delta
{flags}{x} ?
"755"
:
"644"
;
print
{
$gfi
}
"M $mode :$mark $fn\n"
;
print
{
$gfi
}
"\n"
;
}
print
{
$gfi
}
"checkpoint\n"
;
close
$gfi
;
system
"git"
,
"checkout"
;
system
"git"
,
"reset"
,
"--hard"
;
open
my
$gi
,
">"
,
".gitignore"
;
print
$gi
<<EOG;
SCCS
core
old
save
*.log
*.out
*.sv
*.t[gb]z
*.zip
EOG
exists
$sccs_ext
{as} and
print
$gi
<<EOG;
*.[af]o
*.[af]q
*.al
*.bk
*.fa
*.hz
EOG
exists
$sccs_ext
{c} and
print
$gi
<<EOG;
*.[oa]
a.out
EOG
exists
$sccs_ext
{ic} and
print
$gi
<<EOG;
*.ec
*.u
udir
EOG
close
$gi
;
system
"git"
,
"add"
,
".gitignore"
;
system
"git"
,
"commit"
,
"-m"
,
"Add default ignore list"
;
@fail
and
print
STDERR
join
"\n "
,
"The following files could not be converted and were skipped:"
,
@fail
,
"\r"
;