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
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
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