Check-in [6b78df3861]
Not logged in
Overview

SHA1 Hash:6b78df386170d9bc7b06cf9897c6e7ecaa9e88a8
Date: 2008-02-08 21:52:21
User: drh
Comment:Merge in changes from Andreas's branch.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified ci_cvs.txt from [78baac6911] to [837df67f24].

@@ -1,10 +1,10 @@
 ===============================================================================
 
 First experimental codes ...
 
-toosl/import-cvs.tcl
+tools/import-cvs.tcl
 tools/lib/rcsparser.tcl
 
 No actual import, right now only working on getting csets right. The
 code uses CVSROOT/history as foundation, and augments that with data
 from the individual RCS files (commit messages).

Added cvs2fossil.txt version [4a1e39371f]

@@ -1,1 +1,11 @@
 
+Known problems and areas to work on
+===================================
+
+*	Not yet able to handle the specification of multiple projects
+	for one CVS repository. I.e. I can, for example, import all of
+	tcllib, or a single subproject of tcllib, like tklib, but not
+	multiple sub-projects in one go.
+
+*	We have to look into the pass 'InitCsets' and hunt for the
+	cause of the large amount of memory it is gobbling up.

Modified todo-ak.txt from [7f4b3bcffb] to [25be5322be].

@@ -10,10 +10,11 @@
   fossil.
 
 * Think about exposure of functionality as libraries, i.e. Tcl
   packages. Foundations like delta, etc. first, work up to
   higher-levels.
+  => Mark Janssen has started on this.
 
 * Document the merge algorithm.
 
 * Document the xfer protocol.
 

Modified tools/cvs2fossil/lib/c2f_blobstore.tcl from [725b47dd34] to [b63bce5767].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_file.tcl from [8f9fa8b308] to [a5aa8fb6dc].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many
@@ -275,10 +275,12 @@
 
     # # ## ### ##### ######## #############
     ## Pass XII (Import).
 
     method pushto {repository} {
+	log write 2 file {Importing file "$mypath"}
+
 	set ws [$repository workspace]
 	struct::list assign [$self Expand $ws] filemap revmap
 	# filemap = dict (path -> uuid)
 	# revmap  = dict (path -> rid)
 

Modified tools/cvs2fossil/lib/c2f_fossil.tcl from [ecad76ba99] to [7c35d62cbf].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many
@@ -106,21 +106,21 @@
 
 	set message "By $user:\n$message"
 
 	log write 2 fossil {== $user @ [clock format $date]}
 	log write 2 fossil {-> $parent}
-	log write 2 fossil {%% [join [split $message \n] "\n%% "]}
+	log write 9 fossil {%% [join [split $message \n] "\n%% "]}
 
 	lappend cmd Do test-import-manifest $date $message
 	if {$parent ne ""} { lappend cmd -p $parent }
 	foreach {frid fpath flabel} $revisions {
 	    lappend cmd -f $frid $fpath
-	    log write 2 fossil {** <[format %5d $frid]> = <$flabel>}
+	    log write 12 fossil {** <[format %5d $frid]> = <$flabel>}
 	}
 
 	# run fossil test-command performing the import.
-	log write 8 fossil {	[lreplace $cmd 3 3 @@]}
+	log write 12 fossil {	[lreplace $cmd 3 3 @@]}
 
 	$self InWorkspace
 	set res [eval $cmd]
 	$self RestorePwd
 

Modified tools/cvs2fossil/lib/c2f_frev.tcl from [fa500c1612] to [f35156ab47].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_fsym.tcl from [139ee190b5] to [b11a935cc8].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_integrity.tcl from [ec6d87872c] to [cc4461a50b].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_patopsort.tcl from [24672c709e] to [df888ac870].

@@ -120,11 +120,11 @@
 
 	set date [GetTime [lindex [$graph node get $cset timerange] 1] \
 		      [struct::set contains $mysymchangesets $cset] \
 		     message]
 
-	log write 4 atopsort "Changeset @ [format $myatfmt $at]: [format $mycsfmt [$cset str]]$message"
+	log write 4 atopsort "Changeset @ [format $myatfmt $at]: [format $mycsfmt [$cset str]] '[$cset lod]' $message"
 
 	state run {
 	    INSERT INTO cstimestamp (cid,  pos, date)
 	    VALUES                  ($cid, $at, $date)
 	}

Modified tools/cvs2fossil/lib/c2f_pcollar.tcl from [e182265703] to [54fd12d643].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_pcollrev.tcl from [264f332a9e] to [643897c97a].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_pfiltersym.tcl from [3f927ba110] to [b7f9a11eac].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many
@@ -87,10 +87,11 @@
 	    FilterExcludedSymbols
 	    MutateSymbols
 	    AdjustParents
 	    RefineSymbols
 
+	    PrintSymbolTree
 	    repository printrevstatistics
 
 	    # Strict integrity enforces that all meta entries are in
 	    # the same LOD as the revision using them. At this point
 	    # this may not be true any longer. If a NTDB was excluded
@@ -99,11 +100,11 @@
 	    # refer to the now gone LOD symbol. This is fine however,
 	    # it will not affect our ability to use the meta entries
 	    # to distinguish and group revisions into changesets. It
 	    # should be noted that we cannot simply switch the meta
 	    # entries over to the trunk either, as that may cause the
-	    # modified entries to violate the unique-ness constrain
+	    # modified entries to violate the unique-ness constraint
 	    # set on that table.
 	    integrity metarelaxed
 	}
 
 	log write 1 filtersym "Filtering completed"
@@ -510,10 +511,56 @@
 	    INSERT INTO noop
 	    SELECT B.bid, 1
 	    FROM branch B, revision R
 	    WHERE B.root = R.rid
 	    AND   R.op   = 0 -- nothing
+	}
+	return
+    }
+
+    proc maxlen {v str} {
+	upvar 1 $v n
+	set l [string length $str]
+	if {$l <= $n} return
+	set n $l
+	return
+    }
+
+    proc PrintSymbolTree {} {
+	if {![log visible? 9]} return
+
+	array set sym {}
+	set n 0
+	set t 0
+	set c 0
+
+	foreach {s stype cc p ptype} [state run {
+	    SELECT S.name, A.name, S.commit_count, P.name, B.name
+	    FROM   tag T, symbol S, symbol P, symtype A, symtype B
+	    WHERE  S.sid = T.sid
+	    AND    P.sid = T.lod
+	    AND    A.tid = S.type
+	    AND    B.tid = P.type
+	    UNION
+	    SELECT S.name, A.name, S.commit_count, P.name, B.name
+	    FROM   branch B, symbol S, symbol P, symtype A, symtype B
+	    WHERE  S.sid = B.sid
+	    AND    P.sid = B.lod
+	    AND    A.tid = S.type
+	    AND    B.tid = P.type
+	}] {
+	    lappend sym($s) $p $stype $ptype $cc
+	    maxlen n $s
+	    maxlen t $stype
+	    maxlen t $ptype
+	    maxlen c $cc
+	}
+
+	foreach s [lsort -dict [array names sym]] {
+	    struct::list assign $sym($s) p stype ptype cc
+
+	    log write 9 filtersym {Tree: [format %-${t}s $stype] ([format %-${c}d $cc]) [format %-${n}s $s] <-- [format %-${t}s $ptype] $p}
 	}
 	return
     }
 
     # # ## ### ##### ######## #############

Modified tools/cvs2fossil/lib/c2f_pimport.tcl from [2ae743b09e] to [73e5e1d767].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many
@@ -22,10 +22,11 @@
 package require snit                                      ; # OO system.
 package require vc::tools::log                            ; # User feedback.
 package require vc::fossil::import::cvs::repository       ; # Repository management.
 package require vc::fossil::import::cvs::state            ; # State storage.
 package require vc::fossil::import::cvs::fossil           ; # Access to fossil repositories.
+package require vc::fossil::import::cvs::ristate          ; # Import state (revisions)
 
 # # ## ### ##### ######## ############# #####################
 ## Register the pass with the management
 
 vc::fossil::import::cvs::pass define \
@@ -84,26 +85,24 @@
 
 	foreach project [repository projects] {
 	    log write 1 import {Importing project "[$project base]"}
 
 	    set fossil [fossil %AUTO%]
+	    set rstate [ristate %AUTO%]
 
 	    state transaction {
 		# Layer I: Files and their revisions
 		foreach file [$project files] {
-		    set path [$file path]
-		    log write 2 import {Importing file "$path"}
 		    $file pushto $fossil
 		}
 		# Layer II: Changesets
-		array set rstate {}
 		foreach {revision date} [$project revisionsinorder] {
-		    log write 2 import {Importing revision [$revision str]}
-		    $revision pushto rstate $fossil $date
+		    $revision pushto $fossil $date $rstate
 		}
-		unset rstate
 	    }
+
+	    $rstate destroy
 
 	    # At last copy the temporary repository file to its final
 	    # destination and release the associated memory.
 
 	    $fossil finalize [$project base].fsl
@@ -140,10 +139,11 @@
     namespace export import
     namespace eval import {
 	namespace import ::vc::fossil::import::cvs::repository
 	namespace import ::vc::fossil::import::cvs::state
 	namespace import ::vc::fossil::import::cvs::fossil
+	namespace import ::vc::fossil::import::cvs::ristate
 	namespace import ::vc::tools::log
 	log register import
     }
 }
 

Modified tools/cvs2fossil/lib/c2f_pinitcsets.tcl from [97c1e14340] to [eda30d7ee3].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_prev.tcl from [b562462581] to [c1187b458c].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many
@@ -74,10 +74,14 @@
 		WHERE  S.sid = $mysrcid
 	    }]'"
 	}
 	append str "$mytype ${myid}${detail}>"
 	return $str
+    }
+
+    method lod {} {
+	return [$mytypeobj cs_lod $myitems]
     }
 
     method id    {} { return $myid }
     method items {} { return $mytitems }
     method data  {} { return [list $myproject $mytype $mysrcid] }
@@ -389,13 +393,11 @@
 	if {!$kill} return
 	trouble internal "[$self str] depends on itself"
 	return
     }
 
-    method pushto {sv repository date} {
-	upvar 1 $sv state
-
+    method pushto {repository date rstate} {
 	# Generate and import the manifest for this changeset.
 	#
 	# Data needed:
 	# - Commit message               (-- mysrcid -> repository meta)
 	# - User doing the commit        (s.a.)
@@ -405,22 +407,53 @@
 	# - The parent changeset, if any. If there is no parent fossil
 	#   will use the empty base revision as parent.
 	#
 	# - List of the file revisions in the changeset.
 
-	struct::list assign [$myproject getmeta $mysrcid] __ branch user message
-	struct::list assign $branch __ lodname
+	struct::list assign [$myproject getmeta $mysrcid] __ __ user message
+
+	# We derive the lod information directly from the revisions of
+	# the changeset, as the branch part of the meta data (s.a.) is
+	# outdated since pass FilterSymbols.
+
+	set lodname [$self lod]
+
+	log write 2 csets {Importing revision [$self str] on $lodname}
 
 	# Perform the import. As part of that we determine the parent
 	# we need, and convert the list of items in the changeset into
 	# uuids and printable data.
 
-	set uuid [Updatestate state $lodname \
-		      [$repository importrevision [$self str] \
-			   $user $message $date \
-			   [Getparent state $lodname $myproject $myitems] \
-			   [Getrevisioninfo $myitems]]]
+	struct::list assign [Getisdefault $myitems] isdefault lastdefaultontrunk
+
+	log write 8 csets {LOD    '$lodname'}
+	log write 8 csets { def?  $isdefault}
+	log write 8 csets { last? $lastdefaultontrunk}
+
+	set lws  [Getworkspace    $rstate $lodname $myproject $isdefault]
+	$lws add [Getrevisioninfo $myitems]
+
+	set uuid [$repository importrevision [$self str] \
+		      $user $message $date \
+		      [$lws getid] [$lws get]]
+
+	# Remember the imported changeset in the state, under our
+	# LOD. And if it is the last trunk changeset on the vendor
+	# branch then the revision is also the actual root of the
+	# :trunk:, so we remember it as such in the state. However if
+	# the trunk already exists then the changeset cannot be on it
+	# any more. This indicates weirdness in the setup of the
+	# vendor branch, but one we can work around.
+
+	$lws defid $uuid
+	if {$lastdefaultontrunk} {
+	    if {[$rstate has :trunk:]} {
+		log write 2 csets {Multiple changesets declared to be the last trunk changeset on the vendor-branch}
+	    } else {
+		$rstate new :trunk: [$lws name]
+	    }
+	}
 
 	# Remember the whole changeset / uuid mapping, for the tags.
 
 	state run {
 	    INSERT INTO csuuid (cid,   uuid)
@@ -430,92 +463,70 @@
     }
 
     proc Getrevisioninfo {revisions} {
 	set theset ('[join $revisions {','}]')
 	set revisions {}
-	foreach {frid path fname revnr} [state run [subst -nocommands -nobackslashes {
-	    SELECT U.uuid, F.visible, F.name, R.rev
+	foreach {frid path fname revnr rop} [state run [subst -nocommands -nobackslashes {
+	    SELECT U.uuid, F.visible, F.name, R.rev, R.op
 	    FROM   revision R, revuuid U, file F
 	    WHERE  R.rid IN $theset  -- All specified revisions
 	    AND    U.rid = R.rid     -- get fossil uuid of revision
 	    AND    F.fid = R.fid     -- get file of revision
 	}]] {
-	    lappend revisions $frid $path $fname/$revnr
+	    lappend revisions $frid $path $fname/$revnr $rop
 	}
 	return $revisions
     }
 
-    proc Getparent {sv lodname project items} {
-	upvar 1 $sv state
-
-	struct::list assign [Getisdefault $items] isdefault lastdefaultontrunk
-
-	log write 8 csets {LOD    '$lodname'}
-	log write 8 csets { def?  $isdefault}
-	log write 8 csets { last? $lastdefaultontrunk}
-
-	foreach k [lsort [array names state]] {
-	    log write 8 csets {    $k = $state($k)}
-	}
-
-	# See (a) below, we have to remember if the changeset is last
-	# on vendor branch also belonging to trunk even if we find a
-	# parent in the state. The caller will later (after import)
-	# make us the first trunk changeset in the state (See (**)).
-
-	if {$lastdefaultontrunk} {
-	    set state(:vendor:last:) .
-	}
-
-	# The state array holds for each line-of-development (LOD) the
-	# last committed changeset belonging to that LOD.
+    proc Getworkspace {rstate lodname project isdefault} {
+
+	# The state object holds the workspace state of each known
+	# line-of-development (LOD), up to the last committed
+	# changeset belonging to that LOD.
 
 	# (*) Standard handling if in-LOD changesets. If the LOD of
 	#     the current changeset exists in the state (= has been
-	#     committed to) then the stored changeset is the parent we
-	#     are looking for.
-
-	if {[info exists state($lodname)]} {
-	    return $state($lodname)
-	}
-
-	# If the LOD is not yet known the current changeset can either
-	# be
-	# (a) the root of a vendor branch,
-	# (b) the root of the trunk LOD, or
+	#     committed to) then this it has the workspace we are
+	#     looking for.
+
+	if {[$rstate has $lodname]} {
+	    return [$rstate get $lodname]
+	}
+
+	# If the LOD is however not yet known, then the current
+	# changeset can be either of
+	# (a) root of a vendor branch,
+	# (b) root of the trunk LOD, or
 	# (c) the first changeset in a new LOD which was spawned from
 	#     an existing LOD.
 
-	if {$isdefault} {
-	    # In case of (a) the changeset has no parent, signaled by
-	    # the empty string. We do remember if the changeset is
-	    # last on the vendor branch still belonging to trunk, for
-	    # the trunk root.
-	    return {}
-	}
-
-	if {$lodname eq ":trunk:"} {
-	    # This is case (b), and we also can be sure that there is
-	    # no vendor branch changeset which could be our
-	    # parent. That was already dealt with through the
-	    # :vendor:last: signal and code in the caller (setting
-	    # such a changeset up as parent in the state, causing the
-	    # standard LOD handler at (*) to kick in. So, no parent
-	    # here at all.
-	    return {}
-	}
-
-	# Case (c). We find the parent LOD of our LOD and take the
-	# last changeset committed to that as our parent. If that
-	# doesn't exist we have an error on our hands.
+	if {$isdefault || ($lodname eq ":trunk:")} {
+	    # For both (a) and (b) we have to create a new workspace
+	    # for the lod, and it doesn't inherit from anything.
+
+	    # Note that case (b) may never occur. See the variable
+	    # 'lastdefaultontrunk' in the caller (method pushto). This
+	    # flag can the generation of the workspace for the :trunk:
+	    # LOD as well, making it inherit the state of the last
+	    # trunk-changeset on the vendor-branch.
+
+	    return [$rstate new $lodname]
+	}
+
+	# Case (c). We find the parent LOD of our LOD and let the new
+	# workspace inherit from the parent's workspace.
 
 	set plodname [[[$project getsymbol $lodname] parent] name]
 
 	log write 8 csets {pLOD   '$plodname'}
 
-	if {[info exists state($plodname)]} {
-	    return $state($plodname)
+	if {[$rstate has $plodname]} {
+	    return [$rstate new $lodname $plodname]
+	}
+
+	foreach k [lsort [$rstate names]] {
+	    log write 8 csets {    $k = [[$rstate get $k] getid]}
 	}
 
 	trouble internal {Unable to determine changeset parent}
 	return
     }
@@ -532,27 +543,10 @@
 
 	# TODO/CHECK: look for changesets where isdefault/dbchild is
 	# ambigous.
 
 	return [list $def [expr {$last ne ""}]]
-    }
-
-    proc Updatestate {sv lodname uuid} {
-	upvar 1 $sv state
-
-	# Remember the imported changeset in the state, under our
-	# LOD. (**) And if the :vendor:last: signal is present then
-	# the revision is also the actual root of the :trunk:, so
-	# remember it as such.
-
-	set state($lodname) $uuid
-	if {[info exists state(:vendor:last:)]} {
-	    unset state(:vendor:last:)
-	    set state(:trunk:) $uuid
-	}
-
-	return $uuid
     }
 
     typemethod split {cset args} {
 	# As part of the creation of the new changesets specified in
 	# ARGS as sets of items, all subsets of CSET's item set, CSET
@@ -975,12 +969,18 @@
 
     # # ## ### ##### ######## #############
 
     typevariable mychangesets         {} ; # List of all known
 					   # changesets.
-    typevariable mytchangesets -array {} ; # List of all known
-					   # changesets of a type.
+
+    # List of all known changesets of a type.
+    typevariable mytchangesets -array {
+	sym::branch {}
+	sym::tag    {}
+	rev         {}
+    }
+
     typevariable myitemmap     -array {} ; # Map from items (tagged)
 					   # to the list of changesets
 					   # containing it. Each item
 					   # can be used by only one
 					   # changeset.
@@ -1298,10 +1298,25 @@
             AND    CI.iid = B.bid          -- Select all changesets
             AND    C.cid = CI.cid	   -- containing the branches
             AND    C.type = 2		   -- which are branch changesets
 	}]]
     }
+
+    # result = symbol name
+    typemethod cs_lod {revisions} {
+	# Determines the name of the symbol which is the line of
+	# development for the revisions in a changeset.
+
+	set theset ('[join $revisions {','}]')
+	return [state run [subst -nocommands -nobackslashes {
+	    SELECT
+	    DISTINCT L.name
+	    FROM   revision R, symbol L
+	    WHERE  R.rid in $theset        -- Restrict to revisions of interest
+	    AND    L.sid = R.lod           -- Get lod symbol of revision
+	}]]
+    }
 }
 
 # # ## ### ##### ######## ############# #####################
 ## Helper singleton. Commands for tag symbol changesets.
 
@@ -1351,10 +1366,25 @@
 
     # result = list (changeset-id)
     typemethod cs_successors {tags} {
 	# Tags have no successors.
 	return
+    }
+
+    # result = symbol name
+    typemethod cs_lod {tags} {
+	# Determines the name of the symbol which is the line of
+	# development for the tags in a changeset.
+
+	set theset ('[join $tags {','}]')
+	return [state run [subst -nocommands -nobackslashes {
+	    SELECT
+	    DISTINCT L.name
+	    FROM   tag T, symbol L
+	    WHERE  T.tid in $theset        -- Restrict to tags of interest
+	    AND    L.sid = T.lod           -- Get lod symbol of tag
+	}]]
     }
 }
 
 # # ## ### ##### ######## ############# #####################
 ## Helper singleton. Commands for branch symbol changesets.
@@ -1484,10 +1514,25 @@
             AND    CI.iid = T.tid       -- Select all changesets
             AND    C.cid = CI.cid	-- containing the subordinate tags
             AND    C.type = 1		-- which are tag changesets
 	}]]
 	return
+    }
+
+    # result = symbol name
+    typemethod cs_lod {branches} {
+	# Determines the name of the symbol which is the line of
+	# development for the branches in a changeset.
+
+	set theset ('[join $branches {','}]')
+	return [state run [subst -nocommands -nobackslashes {
+	    SELECT
+	    DISTINCT L.name
+	    FROM   branch B, symbol L
+	    WHERE  B.bid in $theset        -- Restrict to branches of interest
+	    AND    L.sid = B.lod           -- Get lod symbol of branch
+	}]]
     }
 
     typemethod limits {branches} {
 	# Notes. This method exists only for branches. It is needed to
 	# get detailed information about a backward branch. It does

Modified tools/cvs2fossil/lib/c2f_project.tcl from [00dc5b3cac] to [5e07a877fd].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_prtopsort.tcl from [bc1fe01638] to [dbb40b4225].

@@ -112,11 +112,11 @@
 	::variable myatfmt
 	::variable mycsfmt
 
 	set cid [$cset id]
 
-	log write 4 rtopsort "Changeset @ [format $myatfmt $at]: [format $mycsfmt [$cset str]] <<[FormatTR $graph $cset]>>"
+	log write 4 rtopsort "Changeset @ [format $myatfmt $at]: [format $mycsfmt [$cset str]] '[$cset lod]' <<[FormatTR $graph $cset]>>"
 	state run {
 	    INSERT INTO csorder (cid,  pos)
 	    VALUES              ($cid, $at)
 	}
 	return

Modified tools/cvs2fossil/lib/c2f_psym.tcl from [e42d2c8c01] to [cdd6e8c604].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many
@@ -46,13 +46,18 @@
     method istrunk {} { return 0 }
 
     method parent {} {
 	return [$myproject getsymbol [state one {
 	    SELECT S.name
-	    FROM preferedparent P, symbol S
-	    WHERE P.sid = $myid
-	    AND   S.sid = P.pid
+	    FROM tag T, symbol S
+	    WHERE T.sid = $myid
+	    AND   S.sid = T.lod
+	UNION
+	    SELECT S.name
+	    FROM branch B, symbol S
+	    WHERE B.sid = $myid
+	    AND   S.sid = B.lod
 	}]]
 	return
     }
 
     # # ## ### ##### ######## #############

Modified tools/cvs2fossil/lib/c2f_ptrunk.tcl from [5b8e8a5464] to [46554f5736].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/c2f_repository.tcl from [620af1dde5] to [1850a8da8e].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Added tools/cvs2fossil/lib/c2f_ristate.tcl version [9cab4d3dc8]

@@ -1,1 +1,106 @@
+## -*- tcl -*-
+# # ## ### ##### ######## ############# #####################
+## Copyright (c) 2008 Andreas Kupries.
+#
+# This software is licensed as described in the file LICENSE, which
+# you should have received as part of this distribution.
+#
+# This software consists of voluntary contributions made by many
+# individuals.  For exact contribution history, see the revision
+# history and logs, available at http://fossil-scm.hwaci.com/fossil
+# # ## ### ##### ######## ############# #####################
+
+## Track the state of revision import. Essentially maps lines of
+## developments to their workspace state.
+
+# # ## ### ##### ######## ############# #####################
+## Requirements
+
+package require Tcl 8.4                               ; # Required runtime.
+package require snit                                  ; # OO system.
+package require struct::list                          ; # List assignment
+package require vc::fossil::import::cvs::wsstate      ; # Workspace state
+package require vc::fossil::import::cvs::integrity    ; # State integrity checks.
+package require vc::tools::log                        ; # User feedback.
+package require vc::tools::trouble                    ; # Error reporting.
+
+# # ## ### ##### ######## ############# #####################
+##
+
+snit::type ::vc::fossil::import::cvs::ristate {
+    # # ## ### ##### ######## #############
+    ## Public API
+
+    constructor {} {
+	# Start with an empty state
+	return
+    }
+
+    method new {lod {parentlod {}}} {
+	# Create the workspace state for a line of development
+	# (LOD). If a parent LOD is specified let the new state
+	# inherit the current state of the parent.
+
+	log write 8 ristate {Open workspace state for LOD "$lod"}
+
+	integrity assert {
+	    ![info exists mystate($lod)]
+	} {Trying to override existing state for lod "$lod"}
+
+	set wss [wsstate ${selfns}::%AUTO% $lod]
+	set mystate($lod) $wss
+
+	if {$parentlod ne ""} {
+	    log write 8 ristate {Inheriting from workspace state for LOD "$parentlod"}
+
+	    integrity assert {
+		[info exists mystate($parentlod)]
+	    } {Trying to inherit from undefined lod "$parentlod"}
+
+	    set pwss $mystate($parentlod)
+
+	    $wss defstate [$pwss getstate]
+	    $wss defid    [$pwss getid]
+	}
+
+	return $wss
+    }
+
+    method get {lod} { return $mystate($lod) }
+    method has {lod} { return [info exists mystate($lod)] }
+
+    method names {} { return [array names mystate] }
+
+    # # ## ### ##### ######## #############
+    ## State
+
+    variable mystate -array {} ; # Map from lines of development
+				 # (identified by name) to their
+				 # workspace state.
+
+    # # ## ### ##### ######## #############
+    ## Configuration
+
+    pragma -hastypeinfo    no  ; # no type introspection
+    pragma -hasinfo        no  ; # no object introspection
+    pragma -hastypemethods no  ; # type is not relevant.
+
+    # # ## ### ##### ######## #############
+}
+
+namespace eval ::vc::fossil::import::cvs {
+    namespace export ristate
+    namespace eval ristate {
+	namespace import ::vc::fossil::import::cvs::wsstate
+	namespace import ::vc::fossil::import::cvs::integrity
+	namespace import ::vc::tools::trouble
+	namespace import ::vc::tools::log
+	log register ristate
+    }
+}
+
+# # ## ### ##### ######## ############# #####################
+## Ready
 
+package provide vc::fossil::import::cvs::ristate 1.0
+return

Added tools/cvs2fossil/lib/c2f_wsstate.tcl version [f84a18f068]

@@ -1,1 +1,118 @@
+## -*- tcl -*-
+# # ## ### ##### ######## ############# #####################
+## Copyright (c) 2008 Andreas Kupries.
+#
+# This software is licensed as described in the file LICENSE, which
+# you should have received as part of this distribution.
+#
+# This software consists of voluntary contributions made by many
+# individuals.  For exact contribution history, see the revision
+# history and logs, available at http://fossil-scm.hwaci.com/fossil
+# # ## ### ##### ######## ############# #####################
+
+## Track the state of a cvs workspace as changesets are committed to
+## it. Nothing actually happens in the filesystem, this is completely
+## virtual.
+
+# # ## ### ##### ######## ############# #####################
+## Requirements
+
+package require Tcl 8.4                             ; # Required runtime.
+package require snit                                ; # OO system.
+package require struct::list                        ; # List assignment
+package require vc::tools::log                      ; # User feedback.
+
+# # ## ### ##### ######## ############# #####################
+##
+
+snit::type ::vc::fossil::import::cvs::wsstate {
+    # # ## ### ##### ######## #############
+    ## Public API
+
+    constructor {lod} {
+	# Start with an empty state
+	set myname $lod
+	return
+    }
+
+    method name {} { return $myname }
+
+    method add {oprevisioninfo} {
+	# oprevisioninfo = list (rid path label op ...) /quadruples
+
+	# Overwrite all changed files (identified by path) with the
+	# new revisions. This keeps all unchanged files. Files marked
+	# as dead are removed.
+
+	foreach {rid path label rop} $oprevisioninfo {
+	    log write 5 wss {$myop($rop) $label}
+
+	    if {$rop < 0} {
+		unset mystate($path)
+	    } else {
+		set mystate($path) [list $rid $label]
+	    }
+	}
+	return
+    }
+
+    method get {} {
+	set res {}
+	foreach path [lsort -dict [array names mystate]] {
+	    struct::list assign $mystate($path) rid label
+	    lappend res $rid $path $label
+	}
+	return $res
+    }
+
+    method defid {id} {
+	set myid $id
+	return
+    }
+
+    method getid {} { return $myid }
+
+    method defstate {s} { array set mystate $s ; return }
+    method getstate {}  { return [array get mystate] }
+
+    # # ## ### ##### ######## #############
+    ## State
+
+    variable myname {}         ; # Name of the LOD the workspace is
+				 # for.
+    variable myid   {}         ; # Record id of the fossil manifest
+				 # associated with the current state.
+    variable mystate -array {} ; # Map from paths to the recordid of
+				 # the file revision behind it, and
+				 # the associated label for logging.
+
+    typevariable myop -array {
+	-1 REM
+	0  ---
+	1  ADD
+	2  CHG
+    }
+
+    # # ## ### ##### ######## #############
+    ## Configuration
+
+    pragma -hastypeinfo    no  ; # no type introspection
+    pragma -hasinfo        no  ; # no object introspection
+    pragma -hastypemethods no  ; # type is not relevant.
+
+    # # ## ### ##### ######## #############
+}
+
+namespace eval ::vc::fossil::import::cvs {
+    namespace export wsstate
+    namespace eval wsstate {
+	namespace import ::vc::tools::log
+	log register wss
+    }
+}
+
+# # ## ### ##### ######## ############# #####################
+## Ready
 
+package provide vc::fossil::import::cvs::wsstate 1.0
+return

Modified tools/cvs2fossil/lib/log.tcl from [4031b6876e] to [63d56912ab].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/misc.tcl from [85ff794a48] to [b4a6c1a890].

@@ -1,8 +1,8 @@
 ## -*- tcl -*-
 # # ## ### ##### ######## ############# #####################
-## Copyright (c) 2007 Andreas Kupries.
+## Copyright (c) 2007-2008 Andreas Kupries.
 #
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
 #
 # This software consists of voluntary contributions made by many

Modified tools/cvs2fossil/lib/pkgIndex.tcl from [a73808ace1] to [8e64440f57].

@@ -31,12 +31,14 @@
 package ifneeded vc::fossil::import::cvs::project::rev      1.0 [list source [file join $dir c2f_prev.tcl]]
 package ifneeded vc::fossil::import::cvs::project::revlink  1.0 [list source [file join $dir c2f_prevlink.tcl]]
 package ifneeded vc::fossil::import::cvs::project::sym      1.0 [list source [file join $dir c2f_psym.tcl]]
 package ifneeded vc::fossil::import::cvs::project::trunk    1.0 [list source [file join $dir c2f_ptrunk.tcl]]
 package ifneeded vc::fossil::import::cvs::repository        1.0 [list source [file join $dir c2f_repository.tcl]]
+package ifneeded vc::fossil::import::cvs::ristate           1.0 [list source [file join $dir c2f_ristate.tcl]]
 package ifneeded vc::fossil::import::cvs::state             1.0 [list source [file join $dir c2f_state.tcl]]
+package ifneeded vc::fossil::import::cvs::wsstate           1.0 [list source [file join $dir c2f_wsstate.tcl]]
 package ifneeded vc::rcs::parser                            1.0 [list source [file join $dir rcsparser.tcl]]
 package ifneeded vc::tools::dot                             1.0 [list source [file join $dir dot.tcl]]
 package ifneeded vc::tools::id                              1.0 [list source [file join $dir id.tcl]]
 package ifneeded vc::tools::log                             1.0 [list source [file join $dir log.tcl]]
 package ifneeded vc::tools::misc                            1.0 [list source [file join $dir misc.tcl]]
 package ifneeded vc::tools::trouble                         1.0 [list source [file join $dir trouble.tcl]]