Fossil

Check-in [348e45b0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:348e45b0d66e5f80b89a5a5101036c5e057c83b2
User & Date: aku 2008-01-30 08:28:34
Context
2008-01-31
05:39
Moved the most complex parts of pushto into their own commands. check-in: 3cd599ca user: aku tags: trunk
2008-01-30
21:53
Branch created tclfossil check-in: abbdb0e8 user: mjanssen tags: tclfossil-1
08:28
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. check-in: 348e45b0 user: aku tags: trunk
08:25
Added placeholder code to the fossil accessor class for the import of a revision. currently only logging the call. check-in: f9e0d23d user: aku tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to tools/cvs2fossil/lib/c2f_pimport.tcl.

43
44
45
46
47
48
49




50
51
52
53
54
55
56
..
80
81
82
83
84
85
86

87
88
89
90
91





92
93
94
95
96
97

98
99
100
101
102
103
104
    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# this pass.

	state use project
	state use file
	state use revision





	# 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,
	    uuid  INTEGER NOT NULL  -- fossil id of the revision
	    --                         unique within the project
................................................................................

	foreach project [repository projects] {
	    log write 1 import {Importing project "[$project base]"}

	    set fossil [fossil %AUTO%]

	    state transaction {

		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.

	    }

	    # At last copy the temporary repository file to its final
	    # destination and release the associated memory.

	    $fossil finalize [$project base].fsl
	}







>
>
>
>







 







>





>
>
>
>
>
|
<
<
<
<
<
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
..
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102





103
104
105
106
107
108
109
110
    typemethod setup {} {
	# Define the names and structure of the persistent state of
	# 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,
	    uuid  INTEGER NOT NULL  -- fossil id of the revision
	    --                         unique within the project
................................................................................

	foreach project [repository projects] {
	    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
		}
		# 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.

	    $fossil finalize [$project base].fsl
	}

Changes to tools/cvs2fossil/lib/c2f_prev.tcl.

386
387
388
389
390
391
392




















































































393
394
395
396
397
398
399
...
539
540
541
542
543
544
545




















546
547
548
549
550
551
552
	}
	log write 0 csets $ftr

	if {!$kill} return
	trouble internal "[$self str] depends on itself"
	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.
	#
................................................................................
    typevariable mycounter        0 ; # Id counter for csets. Last id
				      # used.
    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 getcstypes {} {
	foreach {tid name} [state run {
	    SELECT tid, name FROM cstype;
	}] { set mycstype($name) $tid }
	return
    }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
...
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
	}
	log write 0 csets $ftr

	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.
	#
................................................................................
    typevariable mycounter        0 ; # Id counter for csets. Last id
				      # used.
    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 }
	return
    }

Changes to tools/cvs2fossil/lib/c2f_project.tcl.

15
16
17
18
19
20
21

22
23
24
25
26
27
28
...
154
155
156
157
158
159
160






161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
...
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
# # ## ### ##### ######## ############# #####################
## Requirements

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::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..

# # ## ### ##### ######## ############# #####################
##
................................................................................
	    foreach {name symbol} [array get mysymbol] {
		$symbol persistrev
	    }
	}
	return
    }







    # # ## ### ##### ######## #############
    ## State

    variable mybase           {} ; # Project directory.
    variable myid             {} ; # Project id in the persistent state.
    variable mytrunk          {} ; # Reference to the main line of
				   # 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 mysymbol  -array {} ; # Map symbol names to project-level
				   # symbol objects.

    # # ## ### ##### ######## #############
    ## Internal methods

    proc TheFiles {} {
................................................................................
    namespace export project
    namespace eval project {
	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


    }
}

# # ## ### ##### ######## ############# #####################
## Ready

package provide vc::fossil::import::cvs::project 1.0
return







>







 







>
>
>
>
>
>











|







 







>
>








15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# # ## ### ##### ######## ############# #####################
## Requirements

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..

# # ## ### ##### ######## ############# #####################
##
................................................................................
	    foreach {name symbol} [array get mysymbol] {
		$symbol persistrev
	    }
	}
	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.
    variable mytrunk          {} ; # Reference to the main line of
				   # 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 project belongs to.
    variable mysymbol  -array {} ; # Map symbol names to project-level
				   # symbol objects.

    # # ## ### ##### ######## #############
    ## Internal methods

    proc TheFiles {} {
................................................................................
    namespace export project
    namespace eval project {
	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

Changes to tools/cvs2fossil/lib/c2f_psym.tcl.

38
39
40
41
42
43
44












45
46
47
48
49
50
51
	# Count total number of symbols.
	incr mynum
	return
    }

    method name {} { return $myname }
    method id   {} { return $myid   }













    # # ## ### ##### ######## #############
    ## Symbol type

    method determinetype {} {
	# This is done by a fixed heuristics, with guidance by the
	# user in edge-cases. Contrary to cvs2svn which uses a big







>
>
>
>
>
>
>
>
>
>
>
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
	# Count total number of symbols.
	incr mynum
	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 {} {
	# This is done by a fixed heuristics, with guidance by the
	# user in edge-cases. Contrary to cvs2svn which uses a big

Changes to tools/cvs2fossil/lib/c2f_ptrunk.tcl.

35
36
37
38
39
40
41

42
43
44
45
46
47
48
	$mysymbol destroy
    }

    method name    {} { return $myname }
    method id      {} { return $myid   }
    method istrunk {} { return 1 }
    method symbol  {} { return $self }


    method forceid {id} { set myid $id ; return }

    method defcounts {tc bc cc} {}

    method countasbranch {} {}
    method countastag    {} {}







>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
	$mysymbol destroy
    }

    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} {}

    method countasbranch {} {}
    method countastag    {} {}

Changes to tools/cvs2fossil/lib/c2f_repository.tcl.

81
82
83
84
85
86
87









88
89
90
91
92
93
94
...
256
257
258
259
260
261
262



















263
264
265
266
267
268
269
...
468
469
470
471
472
473
474
475
476
    typemethod defsymbol   {pid name}        { $mysymbol put [list $pid $name] }
    typemethod defmeta     {pid bid aid cid} { $mymeta   put [list $pid $bid $aid $cid] }

    typemethod commitmessageof {mid} {
	struct::list assign [$mymeta keyof $mid] pid bid aid cid
	return [$mycmsg keyof $cid]
    }










    # pass I results
    typemethod printstatistics {} {
	set prlist [TheProjects]
	set npr [llength $prlist]

	log write 2 repository "Statistics: Scanned [nsp $npr project]"
................................................................................

		# 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)
	    }



















	}
	return
    }

    typemethod determinesymboltypes {} {
	foreach project [TheProjects] {
	    $project determinesymboltypes
................................................................................
	namespace import ::vc::tools::log
	log register repository
    }
}

# # ## ### ##### ######## ############# #####################
## Ready

return







>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
...
496
497
498
499
500
501
502

503
    typemethod defsymbol   {pid name}        { $mysymbol put [list $pid $name] }
    typemethod defmeta     {pid bid aid cid} { $mymeta   put [list $pid $bid $aid $cid] }

    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]

	log write 2 repository "Statistics: Scanned [nsp $npr project]"
................................................................................

		# 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
    }

    typemethod determinesymboltypes {} {
	foreach project [TheProjects] {
	    $project determinesymboltypes
................................................................................
	namespace import ::vc::tools::log
	log register repository
    }
}

# # ## ### ##### ######## ############# #####################
## Ready

return