Check-in [348e45b0d6]
Not logged in
Overview

SHA1 Hash:348e45b0d66e5f80b89a5a5101036c5e057c83b2
Date: 2008-01-30 08:28:34
User: aku
Comment:Added basic import of changesets. Note that this code is incomplete with regard to handling the various possible interactions between a vendor-branh and trunk.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified tools/cvs2fossil/lib/c2f_pimport.tcl from [1601bf3ce0] to [2ae743b09e].

@@ -45,10 +45,14 @@
 	# this pass.
 
 	state use project
 	state use file
 	state use revision
+	state use meta
+	state use author
+	state use cmessage
+	state use symbol
 
 	# This data is actually transient, confined to this pass. We
 	# use the state storage only to keep the RAM usage low.
 	state extend revuuid {
 	    rid   INTEGER NOT NULL  REFERENCES revision UNIQUE,
@@ -82,21 +86,23 @@
 	    log write 1 import {Importing project "[$project base]"}
 
 	    set fossil [fossil %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
 		}
-
-		# TODO: Generate manifests for the changesets in the
-		#       project and import them. This needs
-		#       topological traversal. And the creation of
-		#       empty helper baselines for stuff like the root
-		#       of ntdb and such.
+		# Layer II: Changesets
+		array set rstate {}
+		foreach {revision date} [$project revisionsinorder] {
+		    log write 2 import {Importing revision [$revision str]}
+		    $revision pushto rstate $fossil $date
+		}
+		unset rstate
 	    }
 
 	    # At last copy the temporary repository file to its final
 	    # destination and release the associated memory.
 

Modified tools/cvs2fossil/lib/c2f_prev.tcl from [079c4b0014] to [5b323107c1].

@@ -389,10 +389,94 @@
 	if {!$kill} return
 	trouble internal "[$self str] depends on itself"
 	return
     }
 
+    method pushto {sv repository date} {
+	upvar 1 $sv state
+
+	# Generate and import the manifest for this changeset.
+	#
+	# Data needed:
+	# - Commit message               (-- mysrcid -> repository meta)
+	# - User doing the commit        (s.a.)
+	#
+	# - Timestamp of when committed  (command argument)
+	#
+	# - The parent changeset, if any. If there is no parent 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
+
+	# The parent is determined via the line-of-development (LOD)
+	# information of each changeset, and the history of
+	# imports. The last changeset committed to the same LOD is
+	# taken as the parent of the current changeset. If the
+	# changeset is the first on that LOD it can be either spawned
+	# from another LOD, or detached. For the first case we
+	# retrieve the parent LOD of the current LOD symbol (*) and
+	# recheck for a committed changeset. The second case is taken
+	# if that lookup fails as well.
+	#
+	# (*) And this parent was found in previous passes when
+	#     determining the prefered parents of all the symbols.
+
+	# NOTE: The above is incomplete and buggy. Vendor-branches and
+	#       the various possibilities of its interaction with the
+	#       trunk are not fully handled.
+
+	if {[info exists state($lodname)]} {
+	    # LOD exists and has already been committed to.
+	    set parent $state($lodname)
+	} else {
+	    # LOD has not been committed to before, this is the first
+	    # time. Determine the name of the parent LOD.
+
+	    set plodname [[[$myproject getsymbol $lodname] parent] name]
+
+	    if {[info exists state($plodname)]} {
+		# The parental LOD has been committed to, take that
+		# last changeset as the spawnpoint for the new LOD.
+		set parent $state($plodname)
+	    } else {
+		# The parental LOD is not defined (yet). This LOD is
+		# detached. We choose as our parent the automatic
+		# empty root baseline of the target repository.
+		set parent {}
+	    }
+	}
+
+	# Perform the import. As part of that convert the list of
+	# items in the changeset into uuids and printable data.
+
+	set theset ('[join $myitems {','}]')
+	set uuid [$repository importrevision [$self str] \
+		      $user $message $date $parent \
+		      [state run [subst -nocommands -nobackslashes {
+			  SELECT U.uuid, F.name, R.rev
+			  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
+		      }]]]
+
+	# Remember the imported changeset in the state, under our LOD.
+
+	set state($lodname) $uuid
+
+	# Remember the whole changeset / uuid mapping, for the tags.
+
+	state run {
+	    INSERT INTO csuuid (cid,   uuid)
+	    VALUES             ($myid, $uuid)
+	}
+	return
+    }
+
     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
 	# will be dropped from all databases, in and out of memory,
 	# and then destroyed.
@@ -541,10 +625,30 @@
     typevariable mycstype -array {} ; # Map cstypes (names) to persistent
 				      # ids. Note that we have to keep
 				      # the names in the table 'cstype'
 				      # in sync with the names of the
 				      # helper singletons.
+
+    typemethod inorder {projectid} {
+	# Return all revision changesets for the specified project, in
+	# the order given to them by the sort passes. Both the
+	# filtering by project and sorting make use of 'project::rev
+	# rev' impossible.
+
+	set res {}
+	foreach {cid cdate} [state run {
+	    SELECT C.cid, T.date
+	    FROM   changeset C, cstimestamp T
+	    WHERE  C.type = 0          -- limit to revision changesets
+	    AND    C.pid  = $projectid -- limit to changesets in project
+	    AND    T.cid  = C.cid      -- get ordering information
+	    ORDER BY T.date            -- sort into commit order
+	}] {
+	    lappend res $myidmap($cid) $cdate
+	}
+	return $res
+    }
 
     typemethod getcstypes {} {
 	foreach {tid name} [state run {
 	    SELECT tid, name FROM cstype;
 	}] { set mycstype($name) $tid }

Modified tools/cvs2fossil/lib/c2f_project.tcl from [15df810152] to [00dc5b3cac].

@@ -17,10 +17,11 @@
 
 package require Tcl 8.4                                 ; # Required runtime.
 package require snit                                    ; # OO system.
 package require vc::fossil::import::cvs::file           ; # CVS archive file.
 package require vc::fossil::import::cvs::state          ; # State storage.
+package require vc::fossil::import::cvs::project::rev   ; # Changesets.
 package require vc::fossil::import::cvs::project::sym   ; # Per project symbols.
 package require vc::fossil::import::cvs::project::trunk ; # Per project trunk, main lod
 package require vc::tools::log                          ; # User feedback
 package require struct::list                            ; # Advanced list operations..
 
@@ -156,10 +157,16 @@
 	    }
 	}
 	return
     }
 
+    method revisionsinorder {} {
+	return [rev inorder $myid]
+    }
+
+    delegate method getmeta to myrepository
+
     # # ## ### ##### ######## #############
     ## State
 
     variable mybase           {} ; # Project directory.
     variable myid             {} ; # Project id in the persistent state.
@@ -167,11 +174,11 @@
 				   # development for the project.
     variable myfiles   -array {} ; # Maps the rcs archive paths to
 				   # their user-visible files.
     variable myfobj           {} ; # File objects for the rcs archives
     variable myfmap    -array {} ; # Map rcs archive to their object.
-    variable myrepository     {} ; # Repository the prject belongs to.
+    variable myrepository     {} ; # Repository the project belongs to.
     variable mysymbol  -array {} ; # Map symbol names to project-level
 				   # symbol objects.
 
     # # ## ### ##### ######## #############
     ## Internal methods
@@ -212,13 +219,15 @@
 	namespace import ::vc::tools::log
 	namespace import ::vc::fossil::import::cvs::file
 	namespace import ::vc::fossil::import::cvs::state
 	# Import not required, already a child namespace.
 	# namespace import ::vc::fossil::import::cvs::project::sym
+	# Import not required, already a child namespace.
+	# namespace import ::vc::fossil::import::cvs::project::rev
     }
 }
 
 # # ## ### ##### ######## ############# #####################
 ## Ready
 
 package provide vc::fossil::import::cvs::project 1.0
 return

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

@@ -40,10 +40,22 @@
 	return
     }
 
     method name {} { return $myname }
     method id   {} { return $myid   }
+
+    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
+	}]]
+	return
+    }
 
     # # ## ### ##### ######## #############
     ## Symbol type
 
     method determinetype {} {

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

@@ -37,10 +37,11 @@
 
     method name    {} { return $myname }
     method id      {} { return $myid   }
     method istrunk {} { return 1 }
     method symbol  {} { return $self }
+    method parent  {} { return $self }
 
     method forceid {id} { set myid $id ; return }
 
     method defcounts {tc bc cc} {}
 

Modified tools/cvs2fossil/lib/c2f_repository.tcl from [87c45ff178] to [620af1dde5].

@@ -84,10 +84,19 @@
     typemethod commitmessageof {mid} {
 	struct::list assign [$mymeta keyof $mid] pid bid aid cid
 	return [$mycmsg keyof $cid]
     }
 
+    typemethod getmeta {mid} {
+	struct::list assign [$mymeta keyof $mid] pid bid aid cid
+	return [list \
+		    $myprojmap($pid) \
+		    [$mysymbol keyof $bid] \
+		    [$myauthor keyof $aid] \
+		    [$mycmsg   keyof $cid]]
+    }
+
     # pass I results
     typemethod printstatistics {} {
 	set prlist [TheProjects]
 	set npr [llength $prlist]
 
@@ -257,10 +266,29 @@
 		# Note: The type is neither retrieved nor set, for
 		# this is used to load the pass II data, which means
 		# that everything is 'undefined' at this point anyway.
 
 		# future: $symbol load (blockers, and parents)
+	    }
+
+	    # Beyond the symbols we also load the author, commit log,
+	    # and meta information.
+
+	    foreach {aid aname} [state run {
+		SELECT aid, name FROM author
+	    }] {
+		$myauthor map $aid $aname
+	    }
+	    foreach {cid text} [state run {
+		SELECT cid, text FROM cmessage
+	    }] {
+		$mycmsg map $cid $text
+	    }
+	    foreach {mid pid bid aid cid} [state run {
+		SELECT mid, pid, bid, aid, cid FROM meta
+	    }] {
+		$mymeta map $mid [list $pid $bid $aid $cid]
 	    }
 	}
 	return
     }
 
@@ -470,7 +498,6 @@
     }
 }
 
 # # ## ### ##### ######## ############# #####################
 ## Ready
-
 return