The attached script imports an RCS repository into Fossil. It doesn't
support branching nor symbolic names, and it has a few peculiarities
designed to accommodate the RCS repository I just processed.
--
Andy Goth | <andrew.m.goth/at/gmail/dot/com>
#!/usr/bin/env tclsh
package require Tcl 8.6
# Confirm command line arguments.
if {[llength $argv] != 2} {
puts stderr "Usage: [file tail $argv0] INPUT_RCS OUTPUT_FOSSIL"
exit 1
}
set input [file normalize [lindex $argv 0]]
set output [file normalize [lindex $argv 1]]
# Executes a program after printing the command line.
proc run {args} {
puts $args
exec {*}$args
}
# Formats timestamps the way Fossil likes them.
proc fossilTime {timestamp} {
clock format $timestamp -format "%Y-%m-%d %T"
}
# Find all RCS files and load their logs into $database.
set dirs [list $input]
set database {}
while {[llength $dirs]} {
# Dequeue the first directory off the list and enqueue its subdirectories.
set dirs [concat [lassign $dirs dir] [glob -nocomplain -dir $dir -type d *]]
# Process all RCS files inside the directory.
foreach file [glob -nocomplain -directory $dir -type f *,v] {
# Determine the working file name by stripping the input root path, the
# ",v" suffix, and (if present) the RCS subdirectory component.
regsub {/RCS/(?=[^/]*$)} [regsub {,v$} [string range $file\
[expr {[string length $input] + 1}] end] {}] / name
# Obtain the log, sans header.
regsub {.*?\n-{28}\n} [run rlog $file] {} data
# Process each revision.
set start 0
while {[regexp -start $start -indices {\n-{28}\n|\n={77}$} $data sep]} {
# Get the revision body text, and find the start of the next block.
set body [string range $data $start [expr {[lindex $sep 0] - 1}]]
set start [expr {[lindex $sep 1] + 1}]
# Extract the fields from the revision body.
regexp -expanded {
^revision\ ([\d.]+)[^\n]*\n
date:\ ([\d/ :]+);\ *
author:\ ([^;]+);\ *
state:\ [^;]+;\ *
(?:lines:\ [^\n]+)?\n
(.*)$
} $body _ revision date author message
set date [clock scan $date -format "%Y/%m/%d %T"]
# Process the message.
if {[set sep [string first "\n@:" $message]] >= 0} {
set extra [string trim [regsub -line -all {^@: *}\
[string range $message $sep end] {}]]
set message [string trim [string range $message\
0 [expr {$sep - 1}]]]
if {$extra ne {} && $extra ne $message} {
append message \n $extra
}
} else {
set message [string trim $message]
}
# Store the revision data in the database.
lappend database $date $name $revision $author $message
}
}
}
# Sort the database so the oldest entry is first.
set database [lsort -integer -stride 5 $database]
# Create the Fossil repository.
set lastDate [expr {[lindex $database 0] - 1}]
run fossil new --date-override [fossilTime $lastDate] $output
file mkdir tmp
cd tmp
run fossil open $output
# Process all revision data from oldest to newest.
set users [dict create [run fossil user default] {}]
foreach {date name revision author message} $database {
# Forbid equal timestamps.
if {[info exists lastDate] && $date <= $lastDate} {
set date [expr {$lastDate + 1}]
}
# Create users as they are first encountered.
if {![dict exists $users $author]} {
dict set users $author {}
run fossil user new $author {} {}
}
# Extract the file from RCS and place into the temporary directory.
run co -r$revision [file join $input $name] 2> /dev/null
if {![set exists [file exists $name]]} {
file mkdir [file dirname $name]
}
file rename -force [file join $input $name] $name
file attributes $name -permissions\
[expr {[file attributes $name -permissions] | 0600}]
# Make sure the file has Unix line endings.
if {[regexp {, with CRLF line terminators$} [run file $name]]} {
set chan [open $name]
chan configure $chan -translation crlf
set data [chan read $chan]
chan close $chan
set chan [open $name w]
chan puts -nonewline $chan $data
chan close $chan
}
# Add or update the file in the Fossil repository.
if {!$exists} {
run fossil add $name
}
run fossil commit --sha1sum --no-warnings --allow-empty\
--user-override $author --date-override [fossilTime $date]\
--comment $message
}
run fossil close
# vim: set sts=4 sw=4 tw=80 et ft=tcl:
_______________________________________________
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users