Fossil SCM

fossil-scm / tools / cvs2fossil / lib / c2f_pinitcsets.tcl
Source Blame History 379 lines
54d1e35… aku 1 ## -*- tcl -*-
54d1e35… aku 2 # # ## ### ##### ######## ############# #####################
6b78df3… drh 3 ## Copyright (c) 2007-2008 Andreas Kupries.
54d1e35… aku 4 #
54d1e35… aku 5 # This software is licensed as described in the file LICENSE, which
54d1e35… aku 6 # you should have received as part of this distribution.
54d1e35… aku 7 #
54d1e35… aku 8 # This software consists of voluntary contributions made by many
54d1e35… aku 9 # individuals. For exact contribution history, see the revision
54d1e35… aku 10 # history and logs, available at http://fossil-scm.hwaci.com/fossil
54d1e35… aku 11 # # ## ### ##### ######## ############# #####################
54d1e35… aku 12
5f7acef… aku 13 ## Pass V. This pass creates the initial set of project level
5f7acef… aku 14 ## revisions, aka changesets. Later passes will refine them, puts them
5f7acef… aku 15 ## into proper order, set their dependencies, etc.
54d1e35… aku 16
54d1e35… aku 17 # # ## ### ##### ######## ############# #####################
54d1e35… aku 18 ## Requirements
54d1e35… aku 19
54d1e35… aku 20 package require Tcl 8.4 ; # Required runtime.
54d1e35… aku 21 package require snit ; # OO system.
54d1e35… aku 22 package require vc::tools::misc ; # Text formatting.
54d1e35… aku 23 package require vc::tools::log ; # User feedback.
27ed4f7… aku 24 package require vc::tools::mem ; # Memory tracking.
5f7acef… aku 25 package require vc::fossil::import::cvs::repository ; # Repository management.
54d1e35… aku 26 package require vc::fossil::import::cvs::state ; # State storage.
bf83201… aku 27 package require vc::fossil::import::cvs::integrity ; # State integrity checks.
5f7acef… aku 28 package require vc::fossil::import::cvs::project::rev ; # Project level changesets
54d1e35… aku 29
54d1e35… aku 30 # # ## ### ##### ######## ############# #####################
54d1e35… aku 31 ## Register the pass with the management
54d1e35… aku 32
54d1e35… aku 33 vc::fossil::import::cvs::pass define \
54d1e35… aku 34 InitCsets \
54d1e35… aku 35 {Initialize ChangeSets} \
54d1e35… aku 36 ::vc::fossil::import::cvs::pass::initcsets
54d1e35… aku 37
54d1e35… aku 38 # # ## ### ##### ######## ############# #####################
b679ca3… aku 39 ##
54d1e35… aku 40
54d1e35… aku 41 snit::type ::vc::fossil::import::cvs::pass::initcsets {
54d1e35… aku 42 # # ## ### ##### ######## #############
54d1e35… aku 43 ## Public API
54d1e35… aku 44
54d1e35… aku 45 typemethod setup {} {
54d1e35… aku 46 # Define the names and structure of the persistent state of
54d1e35… aku 47 # this pass.
5f7acef… aku 48
e288af3… aku 49 state use project
e288af3… aku 50 state use file
e288af3… aku 51 state use revision
e288af3… aku 52 state use revisionbranchchildren
e288af3… aku 53 state use branch
e288af3… aku 54 state use tag
e288af3… aku 55 state use symbol
e288af3… aku 56 state use meta
5f7acef… aku 57
5f7acef… aku 58 # Data per changeset, namely the project it belongs to, how it
5f7acef… aku 59 # was induced (revision or symbol), plus reference to the
5f7acef… aku 60 # primary entry causing it (meta entry or symbol). An adjunct
5f7acef… aku 61 # table translates the type id's into human readable labels.
5f7acef… aku 62
e288af3… aku 63 state extend changeset {
5f7acef… aku 64 cid INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
5f7acef… aku 65 pid INTEGER NOT NULL REFERENCES project,
5f7acef… aku 66 type INTEGER NOT NULL REFERENCES cstype,
5f7acef… aku 67 src INTEGER NOT NULL -- REFERENCES meta|symbol (type dependent)
5f7acef… aku 68 }
e288af3… aku 69 state extend cstype {
5f7acef… aku 70 tid INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
5f7acef… aku 71 name TEXT NOT NULL,
5f7acef… aku 72 UNIQUE (name)
5f7acef… aku 73 }
215d2f1… aku 74 # Note: Keep the labels used here in sync with the names for
215d2f1… aku 75 # singleton helper classes for 'project::rev'. They are
215d2f1… aku 76 # the valid type names for changesets and also hardwired
215d2f1… aku 77 # in some code.
5f7acef… aku 78 state run {
5f7acef… aku 79 INSERT INTO cstype VALUES (0,'rev');
215d2f1… aku 80 INSERT INTO cstype VALUES (1,'sym::tag');
215d2f1… aku 81 INSERT INTO cstype VALUES (2,'sym::branch');
215d2f1… aku 82 }
215d2f1… aku 83
215d2f1… aku 84 # Map from changesets to the (file level) revisions, tags, or
215d2f1… aku 85 # branches they contain. The pos'ition provides an order of
215d2f1… aku 86 # the items within a changeset. They are unique within the
215d2f1… aku 87 # changeset. The items are in principle unique, if we were
215d2f1… aku 88 # looking only at relevant changesets. However as they come
215d2f1… aku 89 # from disparate sources the same id may have different
215d2f1… aku 90 # meaning, be in different changesets and so is formally not
215d2f1… aku 91 # unique. So we can only say that it is unique within the
215d2f1… aku 92 # changeset. The integrity module has stronger checks.
215d2f1… aku 93
e288af3… aku 94 state extend csitem {
5f7acef… aku 95 cid INTEGER NOT NULL REFERENCES changeset,
5f7acef… aku 96 pos INTEGER NOT NULL,
80b1e89… aku 97 iid INTEGER NOT NULL, -- REFERENCES revision|tag|branch
5f7acef… aku 98 UNIQUE (cid, pos),
80b1e89… aku 99 UNIQUE (cid, iid)
9c57055… aku 100 } { iid }
9c57055… aku 101 # Index on: iid (successor/predecessor retrieval)
5f7acef… aku 102
5f7acef… aku 103 project::rev getcstypes
54d1e35… aku 104 return
54d1e35… aku 105 }
54d1e35… aku 106
54d1e35… aku 107 typemethod load {} {
54d1e35… aku 108 # Pass manager interface. Executed to load data computed by
54d1e35… aku 109 # this pass into memory when this pass is skipped instead of
54d1e35… aku 110 # executed.
24c0b66… aku 111
e288af3… aku 112 state use changeset
e288af3… aku 113 state use csitem
e288af3… aku 114 state use cstype
215d2f1… aku 115
49dd66f… aku 116 # Need the types first, the constructor used inside of the
49dd66f… aku 117 # 'load' below uses them to assert the correctness of type
49dd66f… aku 118 # names.
5f7acef… aku 119 project::rev getcstypes
9e1b461… aku 120 project::rev load ::vc::fossil::import::cvs::repository
65be27a… aku 121 project::rev loadcounter
54d1e35… aku 122 return
54d1e35… aku 123 }
54d1e35… aku 124
54d1e35… aku 125 typemethod run {} {
54d1e35… aku 126 # Pass manager interface. Executed to perform the
54d1e35… aku 127 # functionality of the pass.
5f7acef… aku 128
5f7acef… aku 129 state transaction {
f46458d… aku 130 CreateRevisionChangesets ; # Group file revisions into
f46458d… aku 131 # preliminary csets and split
f46458d… aku 132 # them based on internal
f46458d… aku 133 # conflicts.
f46458d… aku 134 CreateSymbolChangesets ; # Create csets for tags and
f46458d… aku 135 # branches.
8c6488d… aku 136 }
8c6488d… aku 137
8c6488d… aku 138 repository printcsetstatistics
00bf8c1… aku 139 integrity changesets
f46458d… aku 140
f46458d… aku 141 # Load the changesets for use by the next passes.
f46458d… aku 142 project::rev load ::vc::fossil::import::cvs::repository
f46458d… aku 143 project::rev loadcounter
54d1e35… aku 144 return
54d1e35… aku 145 }
54d1e35… aku 146
54d1e35… aku 147 typemethod discard {} {
54d1e35… aku 148 # Pass manager interface. Executed for all passes after the
54d1e35… aku 149 # run passes, to remove all data of this pass from the state,
54d1e35… aku 150 # as being out of date.
5f7acef… aku 151
5f7acef… aku 152 state discard changeset
5f7acef… aku 153 state discard cstype
80b1e89… aku 154 state discard csitem
54d1e35… aku 155 return
54d1e35… aku 156 }
54d1e35… aku 157
54d1e35… aku 158 # # ## ### ##### ######## #############
54d1e35… aku 159 ## Internal methods
5f7acef… aku 160
24c0b66… aku 161 proc CreateRevisionChangesets {} {
5f7acef… aku 162 log write 3 initcsets {Create changesets based on revisions}
5f7acef… aku 163
5f7acef… aku 164 # To get the initial of changesets we first group all file
5f7acef… aku 165 # level revisions using the same meta data entry together. As
5f7acef… aku 166 # the meta data encodes not only author and log message, but
5f7acef… aku 167 # also line of development and project we can be sure that
5f7acef… aku 168 # revisions in different project and lines of development are
5f7acef… aku 169 # not grouped together. In contrast to cvs2svn we do __not__
5f7acef… aku 170 # use distance in time between revisions to break them
5f7acef… aku 171 # apart. We have seen CVS repositories (from SF) where a
5f7acef… aku 172 # single commit contained revisions several hours apart,
5f7acef… aku 173 # likely due to trouble on the server hosting the repository.
5f7acef… aku 174
5f7acef… aku 175 # We order the revisions here by time, this will help the
5f7acef… aku 176 # later passes (avoids joins later to get at the ordering
5f7acef… aku 177 # info).
5f7acef… aku 178
f46458d… aku 179 # The changesets made from these groups are immediately
f46458d… aku 180 # inspected for internal conflicts and any such are broken by
f46458d… aku 181 # splitting the problematic changeset into multiple
f46458d… aku 182 # fragments. The results are changesets which have no internal
f46458d… aku 183 # dependencies, only external ones.
f46458d… aku 184
f46458d… aku 185 set n 0
f46458d… aku 186 set nx 0
5f7acef… aku 187
5f7acef… aku 188 set lastmeta {}
5f7acef… aku 189 set lastproject {}
5f7acef… aku 190 set revisions {}
5f7acef… aku 191
5f7acef… aku 192 # Note: We could have written this loop to create the csets
5f7acef… aku 193 # early, extending them with all their revisions. This
5f7acef… aku 194 # however would mean lots of (slow) method invokations
5f7acef… aku 195 # on the csets. Doing it like this, late creation, means
5f7acef… aku 196 # less such calls. None, but the creation itself.
5f7acef… aku 197
27ed4f7… aku 198 log write 14 initcsets meta_begin
27ed4f7… aku 199 mem::mark
6559f32… aku 200 state foreachrow {
6559f32… aku 201 SELECT M.mid AS xmid,
6559f32… aku 202 R.rid AS xrid,
6559f32… aku 203 M.pid AS xpid
6559f32… aku 204 FROM revision R,
6559f32… aku 205 meta M -- R ==> M, using PK index of M.
5f7acef… aku 206 WHERE R.mid = M.mid
5f7acef… aku 207 ORDER BY M.mid, R.date
6559f32… aku 208 } {
27ed4f7… aku 209 log write 14 initcsets meta_next
27ed4f7… aku 210
6559f32… aku 211 if {$lastmeta != $xmid} {
5f7acef… aku 212 if {[llength $revisions]} {
5f7acef… aku 213 incr n
5f7acef… aku 214 set p [repository projectof $lastproject]
27ed4f7… aku 215 log write 14 initcsets meta_cset_begin
27ed4f7… aku 216 mem::mark
f46458d… aku 217 set cset [project::rev %AUTO% $p rev $lastmeta $revisions]
27ed4f7… aku 218 log write 14 initcsets meta_cset_done
efec424… aku 219 set spawned [$cset breakinternaldependencies nx]
f46458d… aku 220 $cset persist
f46458d… aku 221 $cset destroy
efec424… aku 222 foreach cset $spawned { $cset persist ; $cset destroy }
27ed4f7… aku 223 mem::mark
5f7acef… aku 224 set revisions {}
5f7acef… aku 225 }
6559f32… aku 226 set lastmeta $xmid
6559f32… aku 227 set lastproject $xpid
5f7acef… aku 228 }
6559f32… aku 229 lappend revisions $xrid
5f7acef… aku 230 }
5f7acef… aku 231
5f7acef… aku 232 if {[llength $revisions]} {
5f7acef… aku 233 incr n
5f7acef… aku 234 set p [repository projectof $lastproject]
27ed4f7… aku 235 log write 14 initcsets meta_cset_begin
27ed4f7… aku 236 mem::mark
f46458d… aku 237 set cset [project::rev %AUTO% $p rev $lastmeta $revisions]
27ed4f7… aku 238 log write 14 initcsets meta_cset_done
efec424… aku 239 set spawned [$cset breakinternaldependencies nx]
f46458d… aku 240 $cset persist
f46458d… aku 241 $cset destroy
efec424… aku 242 foreach cset $spawned { $cset persist ; $cset destroy }
27ed4f7… aku 243 mem::mark
5f7acef… aku 244 }
5f7acef… aku 245
27ed4f7… aku 246 log write 14 initcsets meta_done
27ed4f7… aku 247 mem::mark
27ed4f7… aku 248
f46458d… aku 249 log write 4 initcsets "Created and saved [nsp $n {revision changeset}]"
f46458d… aku 250 log write 4 initcsets "Created and saved [nsp $nx {additional revision changeset}]"
f46458d… aku 251
f46458d… aku 252 mem::mark
f46458d… aku 253 log write 4 initcsets Ok.
5f7acef… aku 254 return
5f7acef… aku 255 }
5f7acef… aku 256
24c0b66… aku 257 proc CreateSymbolChangesets {} {
5f7acef… aku 258 log write 3 initcsets {Create changesets based on symbols}
27ed4f7… aku 259 mem::mark
5f7acef… aku 260
5f7acef… aku 261 # Tags and branches induce changesets as well, containing the
5f7acef… aku 262 # revisions they are attached to (tags), or spawned from
5f7acef… aku 263 # (branches).
5f7acef… aku 264
5f7acef… aku 265 set n 0
5f7acef… aku 266
5f7acef… aku 267 # First process the tags, then the branches. We know that
5f7acef… aku 268 # their ids do not overlap with each other.
5f7acef… aku 269
5f7acef… aku 270 set lastsymbol {}
215d2f1… aku 271 set lastproject {}
27f093d… aku 272 set tags {}
27f093d… aku 273
6559f32… aku 274 state foreachrow {
6559f32… aku 275 SELECT S.sid AS xsid,
6559f32… aku 276 T.tid AS xtid,
6559f32… aku 277 S.pid AS xpid
6559f32… aku 278 FROM tag T,
6559f32… aku 279 symbol S -- T ==> R/S, using PK indices of R, S.
27f093d… aku 280 WHERE T.sid = S.sid
27f093d… aku 281 ORDER BY S.sid, T.tid
6559f32… aku 282 } {
6559f32… aku 283 if {$lastsymbol != $xsid} {
27f093d… aku 284 if {[llength $tags]} {
27f093d… aku 285 incr n
27f093d… aku 286 set p [repository projectof $lastproject]
f46458d… aku 287 set cset [project::rev %AUTO% $p sym::tag $lastsymbol $tags]
27f093d… aku 288 set tags {}
f46458d… aku 289 $cset persist
f46458d… aku 290 $cset destroy
27f093d… aku 291 }
6559f32… aku 292 set lastsymbol $xsid
6559f32… aku 293 set lastproject $xpid
27f093d… aku 294 }
6559f32… aku 295 lappend tags $xtid
27f093d… aku 296 }
27f093d… aku 297
27f093d… aku 298 if {[llength $tags]} {
27f093d… aku 299 incr n
27f093d… aku 300 set p [repository projectof $lastproject]
f46458d… aku 301 set cset [project::rev %AUTO% $p sym::tag $lastsymbol $tags]
f46458d… aku 302 $cset persist
f46458d… aku 303 $cset destroy
5f7acef… aku 304 }
5f7acef… aku 305
5f7acef… aku 306 set lastsymbol {}
215d2f1… aku 307 set lasproject {}
27f093d… aku 308 set branches {}
27f093d… aku 309
6559f32… aku 310 state foreachrow {
6559f32… aku 311 SELECT S.sid AS xsid,
6559f32… aku 312 B.bid AS xbid,
6559f32… aku 313 S.pid AS xpid
6559f32… aku 314 FROM branch B,
6559f32… aku 315 symbol S -- B ==> R/S, using PK indices of R, S.
f46458d… aku 316 WHERE B.sid = S.sid
f46458d… aku 317 ORDER BY S.sid, B.bid
6559f32… aku 318 } {
6559f32… aku 319 if {$lastsymbol != $xsid} {
f46458d… aku 320 if {[llength $branches]} {
f46458d… aku 321 incr n
f46458d… aku 322 set p [repository projectof $lastproject]
f46458d… aku 323 set cset [project::rev %AUTO% $p sym::branch $lastsymbol $branches]
f46458d… aku 324 set branches {}
f46458d… aku 325 $cset persist
f46458d… aku 326 $cset destroy
f46458d… aku 327 }
6559f32… aku 328 set lastsymbol $xsid
6559f32… aku 329 set lastproject $xpid
f46458d… aku 330 }
6559f32… aku 331 lappend branches $xbid
f46458d… aku 332 }
f46458d… aku 333
f46458d… aku 334 if {[llength $branches]} {
f46458d… aku 335 incr n
f46458d… aku 336 set p [repository projectof $lastproject]
f46458d… aku 337 set cset [project::rev %AUTO% $p sym::branch $lastsymbol $branches]
f46458d… aku 338 $cset persist
f46458d… aku 339 $cset destroy
f46458d… aku 340 }
f46458d… aku 341
f46458d… aku 342 log write 4 initcsets "Created and saved [nsp $n {symbol changeset}]"
f46458d… aku 343 mem::mark
5f7acef… aku 344 return
5f7acef… aku 345 }
54d1e35… aku 346
54d1e35… aku 347 # # ## ### ##### ######## #############
54d1e35… aku 348 ## Configuration
54d1e35… aku 349
54d1e35… aku 350 pragma -hasinstances no ; # singleton
54d1e35… aku 351 pragma -hastypeinfo no ; # no introspection
54d1e35… aku 352 pragma -hastypedestroy no ; # immortal
54d1e35… aku 353
54d1e35… aku 354 # # ## ### ##### ######## #############
54d1e35… aku 355 }
54d1e35… aku 356
54d1e35… aku 357 namespace eval ::vc::fossil::import::cvs::pass {
54d1e35… aku 358 namespace export initcsets
54d1e35… aku 359 namespace eval initcsets {
5f7acef… aku 360 namespace import ::vc::fossil::import::cvs::repository
54d1e35… aku 361 namespace import ::vc::fossil::import::cvs::state
bf83201… aku 362 namespace import ::vc::fossil::import::cvs::integrity
5f7acef… aku 363 namespace eval project {
5f7acef… aku 364 namespace import ::vc::fossil::import::cvs::project::rev
27ed4f7… aku 365 }
27ed4f7… aku 366 namespace eval mem {
27ed4f7… aku 367 namespace import ::vc::tools::mem::mark
5f7acef… aku 368 }
5f7acef… aku 369 namespace import ::vc::tools::misc::*
54d1e35… aku 370 namespace import ::vc::tools::log
54d1e35… aku 371 log register initcsets
54d1e35… aku 372 }
54d1e35… aku 373 }
54d1e35… aku 374
54d1e35… aku 375 # # ## ### ##### ######## ############# #####################
54d1e35… aku 376 ## Ready
54d1e35… aku 377
54d1e35… aku 378 package provide vc::fossil::import::cvs::pass::initcsets 1.0
54d1e35… aku 379 return

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button