Fossil SCM

Continued work on the import of branches. Main principle now is to handle the branches vertically. First the trunk, then the branch starting with the first unprocessed changeset, and so forth. Looks more promising than the previous approach. Currently handles just a bit over half of the test projects (11 of 21 in 6 repositories).

aku 2007-09-26 05:06 trunk
Commit 72dac950c36d76f5e6b9b5d806a2c2eda1507444
+29 -26
--- tools/lib/cvs.tcl
+++ tools/lib/cvs.tcl
@@ -11,10 +11,12 @@
1111
package require vc::tools::trouble ; # Error handling
1212
package require vc::cvs::cmd ; # Access to cvs application.
1313
package require vc::cvs::ws::files ; # Scan CVS repository for relevant files.
1414
package require vc::cvs::ws::timeline ; # Manage timeline of all changes.
1515
package require vc::cvs::ws::csets ; # Manage the changesets found in the timeline
16
+package require vc::cvs::ws::branch ; # Branch database
17
+package require vc::cvs::ws::sig ; # Changeset file/rev signatures
1618
1719
namespace eval ::vc::cvs::ws {
1820
vc::tools::log::system cvs
1921
namespace import ::vc::tools::log::write
2022
namespace import ::vc::rcs::parser::process
@@ -213,11 +215,14 @@
213215
set operation [Operation $rev $stat($rev)]
214216
NoteDeadRoots $f $rev $operation
215217
timeline::add $date($rev) $f $rev $operation $auth($rev) $cmsg($rev)
216218
incr n
217219
}
218
- #B Extend branch management
220
+
221
+ if {[info exists md(symbol)]} {
222
+ branch::def $f date $md(symbol)
223
+ }
219224
220225
unset md
221226
unset date
222227
unset auth
223228
unset cmsg
@@ -240,13 +245,14 @@
240245
}
241246
return
242247
}
243248
244249
proc ::vc::cvs::ws::Operation {rev state} {
245
- if {$state eq "dead"} {return "R"} ; # Removed
246
- if {$rev eq "1.1"} {return "A"} ; # Added
247
- return "M" ; # Modified
250
+ if {$state eq "dead"} {return "R"} ; # Removed
251
+ if {$rev eq "1.1"} {return "A"} ; # Added
252
+ if {[string match *.1.1 $rev]} {return "A"} ; # Added on a branch
253
+ return "M" ; # Modified
248254
}
249255
250256
proc ::vc::cvs::ws::MakeChangesets {} {
251257
write 0 cvs "Generating changesets from timeline"
252258
@@ -324,24 +330,16 @@
324330
write 0 cvs "Found [NSIPL $t {trunk changeset}], [NSIPL [llength $remainder] {branch changeset}]"
325331
return $remainder
326332
}
327333
328334
proc ::vc::cvs::ws::ProcessBranch {cslist} {
329
- write 0 cvs "Processing the remaining changesets"
335
+ write 0 cvs "Processing the remaining [SIPL [llength $cslist] changeset "[llength $cslist] changesets"]"
330336
331337
set base [lindex $cslist 0]
332338
set cslist [lrange $cslist 1 end]
333339
334
- set remainder {}
335
- set t 0
336
-
337
- ### ### ### ######### ######### #########
338
- ## Dump data of the unprocessing changeset
339
-
340
- puts /${base}/_________________
341
- array set cs [csets::get $base]
342
- parray cs
340
+ csets::DUMP $base
343341
344342
# Which branch does base belong to?
345343
# - It has to be the base of an unprocessed branch!
346344
# Otherwise it would have been on either the trunk
347345
# or an already processed branch.
@@ -352,38 +350,43 @@
352350
# versions we know the root versions of these files, and we
353351
# can determine the changesets they are in => Intersection
354352
# plus cap from previous contraint gives us the possible
355353
# candidates.
356354
357
- # ### ### ### ######### ######### #########
358
- exit
355
+ write 4 cvs "Branch base $base"
356
+
357
+ ::foreach {tag rootsig} [branch::find [csets::get $base]] break
358
+
359
+ write 4 cvs "Branch tag $tag"
360
+ write 4 cvs "Root sig $rootsig"
361
+
362
+ set root [sig::find $base $rootsig]
359363
360
- set tag [FindBranch $base ..]
361
- set root [FindRoot $tag ...]
364
+ write 4 cvs "Branch root $root"
362365
366
+ write 0 cvs "Changeset $base, starting branch \"$tag\", rooted at $root"
363367
csets::setParentOf $base $root
364368
365
- foreach c $cslist {
366
- if {[csets::sameBranch $c $base]} {
369
+ set remainder {}
370
+ set t 1
371
+
372
+ ::foreach c $cslist {
373
+ #csets::DUMP $c
374
+ if {[csets::sameBranch $c $base $tag]} {
367375
csets::setParentOf $c $base
368376
set base $c
369377
incr t
370378
lappend importable $c
371379
} else {
372380
lappend remainder $c
373381
}
374382
}
375383
376
- #write 0 cvs "Found [NSIPL $t {trunk changeset}], [NSIPL [llength $remainder] {branch changeset}]"
384
+ write 0 cvs "Found [NSIPL $t "$tag changeset"], [NSIPL [llength $remainder] changeset] outside"
377385
return $remainder
378386
}
379387
380
-#TBD
381
-#... FindBranch
382
-#... FindRoot
383
-#... SameBranch
384
-
385388
proc ::vc::cvs::ws::Checkout {f r} {
386389
variable base
387390
variable project
388391
389392
# Added or modified, put the requested version of the file into
390393
391394
ADDED tools/lib/cvs_branch.tcl
--- tools/lib/cvs.tcl
+++ tools/lib/cvs.tcl
@@ -11,10 +11,12 @@
11 package require vc::tools::trouble ; # Error handling
12 package require vc::cvs::cmd ; # Access to cvs application.
13 package require vc::cvs::ws::files ; # Scan CVS repository for relevant files.
14 package require vc::cvs::ws::timeline ; # Manage timeline of all changes.
15 package require vc::cvs::ws::csets ; # Manage the changesets found in the timeline
 
 
16
17 namespace eval ::vc::cvs::ws {
18 vc::tools::log::system cvs
19 namespace import ::vc::tools::log::write
20 namespace import ::vc::rcs::parser::process
@@ -213,11 +215,14 @@
213 set operation [Operation $rev $stat($rev)]
214 NoteDeadRoots $f $rev $operation
215 timeline::add $date($rev) $f $rev $operation $auth($rev) $cmsg($rev)
216 incr n
217 }
218 #B Extend branch management
 
 
 
219
220 unset md
221 unset date
222 unset auth
223 unset cmsg
@@ -240,13 +245,14 @@
240 }
241 return
242 }
243
244 proc ::vc::cvs::ws::Operation {rev state} {
245 if {$state eq "dead"} {return "R"} ; # Removed
246 if {$rev eq "1.1"} {return "A"} ; # Added
247 return "M" ; # Modified
 
248 }
249
250 proc ::vc::cvs::ws::MakeChangesets {} {
251 write 0 cvs "Generating changesets from timeline"
252
@@ -324,24 +330,16 @@
324 write 0 cvs "Found [NSIPL $t {trunk changeset}], [NSIPL [llength $remainder] {branch changeset}]"
325 return $remainder
326 }
327
328 proc ::vc::cvs::ws::ProcessBranch {cslist} {
329 write 0 cvs "Processing the remaining changesets"
330
331 set base [lindex $cslist 0]
332 set cslist [lrange $cslist 1 end]
333
334 set remainder {}
335 set t 0
336
337 ### ### ### ######### ######### #########
338 ## Dump data of the unprocessing changeset
339
340 puts /${base}/_________________
341 array set cs [csets::get $base]
342 parray cs
343
344 # Which branch does base belong to?
345 # - It has to be the base of an unprocessed branch!
346 # Otherwise it would have been on either the trunk
347 # or an already processed branch.
@@ -352,38 +350,43 @@
352 # versions we know the root versions of these files, and we
353 # can determine the changesets they are in => Intersection
354 # plus cap from previous contraint gives us the possible
355 # candidates.
356
357 # ### ### ### ######### ######### #########
358 exit
 
 
 
 
 
 
359
360 set tag [FindBranch $base ..]
361 set root [FindRoot $tag ...]
362
 
363 csets::setParentOf $base $root
364
365 foreach c $cslist {
366 if {[csets::sameBranch $c $base]} {
 
 
 
 
367 csets::setParentOf $c $base
368 set base $c
369 incr t
370 lappend importable $c
371 } else {
372 lappend remainder $c
373 }
374 }
375
376 #write 0 cvs "Found [NSIPL $t {trunk changeset}], [NSIPL [llength $remainder] {branch changeset}]"
377 return $remainder
378 }
379
380 #TBD
381 #... FindBranch
382 #... FindRoot
383 #... SameBranch
384
385 proc ::vc::cvs::ws::Checkout {f r} {
386 variable base
387 variable project
388
389 # Added or modified, put the requested version of the file into
390
391 DDED tools/lib/cvs_branch.tcl
--- tools/lib/cvs.tcl
+++ tools/lib/cvs.tcl
@@ -11,10 +11,12 @@
11 package require vc::tools::trouble ; # Error handling
12 package require vc::cvs::cmd ; # Access to cvs application.
13 package require vc::cvs::ws::files ; # Scan CVS repository for relevant files.
14 package require vc::cvs::ws::timeline ; # Manage timeline of all changes.
15 package require vc::cvs::ws::csets ; # Manage the changesets found in the timeline
16 package require vc::cvs::ws::branch ; # Branch database
17 package require vc::cvs::ws::sig ; # Changeset file/rev signatures
18
19 namespace eval ::vc::cvs::ws {
20 vc::tools::log::system cvs
21 namespace import ::vc::tools::log::write
22 namespace import ::vc::rcs::parser::process
@@ -213,11 +215,14 @@
215 set operation [Operation $rev $stat($rev)]
216 NoteDeadRoots $f $rev $operation
217 timeline::add $date($rev) $f $rev $operation $auth($rev) $cmsg($rev)
218 incr n
219 }
220
221 if {[info exists md(symbol)]} {
222 branch::def $f date $md(symbol)
223 }
224
225 unset md
226 unset date
227 unset auth
228 unset cmsg
@@ -240,13 +245,14 @@
245 }
246 return
247 }
248
249 proc ::vc::cvs::ws::Operation {rev state} {
250 if {$state eq "dead"} {return "R"} ; # Removed
251 if {$rev eq "1.1"} {return "A"} ; # Added
252 if {[string match *.1.1 $rev]} {return "A"} ; # Added on a branch
253 return "M" ; # Modified
254 }
255
256 proc ::vc::cvs::ws::MakeChangesets {} {
257 write 0 cvs "Generating changesets from timeline"
258
@@ -324,24 +330,16 @@
330 write 0 cvs "Found [NSIPL $t {trunk changeset}], [NSIPL [llength $remainder] {branch changeset}]"
331 return $remainder
332 }
333
334 proc ::vc::cvs::ws::ProcessBranch {cslist} {
335 write 0 cvs "Processing the remaining [SIPL [llength $cslist] changeset "[llength $cslist] changesets"]"
336
337 set base [lindex $cslist 0]
338 set cslist [lrange $cslist 1 end]
339
340 csets::DUMP $base
 
 
 
 
 
 
 
 
341
342 # Which branch does base belong to?
343 # - It has to be the base of an unprocessed branch!
344 # Otherwise it would have been on either the trunk
345 # or an already processed branch.
@@ -352,38 +350,43 @@
350 # versions we know the root versions of these files, and we
351 # can determine the changesets they are in => Intersection
352 # plus cap from previous contraint gives us the possible
353 # candidates.
354
355 write 4 cvs "Branch base $base"
356
357 ::foreach {tag rootsig} [branch::find [csets::get $base]] break
358
359 write 4 cvs "Branch tag $tag"
360 write 4 cvs "Root sig $rootsig"
361
362 set root [sig::find $base $rootsig]
363
364 write 4 cvs "Branch root $root"
 
365
366 write 0 cvs "Changeset $base, starting branch \"$tag\", rooted at $root"
367 csets::setParentOf $base $root
368
369 set remainder {}
370 set t 1
371
372 ::foreach c $cslist {
373 #csets::DUMP $c
374 if {[csets::sameBranch $c $base $tag]} {
375 csets::setParentOf $c $base
376 set base $c
377 incr t
378 lappend importable $c
379 } else {
380 lappend remainder $c
381 }
382 }
383
384 write 0 cvs "Found [NSIPL $t "$tag changeset"], [NSIPL [llength $remainder] changeset] outside"
385 return $remainder
386 }
387
 
 
 
 
 
388 proc ::vc::cvs::ws::Checkout {f r} {
389 variable base
390 variable project
391
392 # Added or modified, put the requested version of the file into
393
394 DDED tools/lib/cvs_branch.tcl
--- a/tools/lib/cvs_branch.tcl
+++ b/tools/lib/cvs_branch.tcl
@@ -0,0 +1,342 @@
1
+
2
+
3
+namespace eval ::vc::cvs::ws::branch {}
4
+
5
+# Trivial storage of all branch data as a rectangular table. We can
6
+# think up a better suited storage system later, when we know what
7
+# type of queries are made to this module.
8
+
9
+proc ::vc::cvs::ws::branch::def {f dv deflist} {
10
+ upvar 1 $dv date
11
+ variable bra
12
+ foreach {tag rev} $deflist {
13
+ # ignore non-branch tags
14
+ if {[llength [split $rev .]] < 4} continue
15
+
16
+ if 0 {
17
+ if { ($rev ne "1.1.1.1") && ![string match *.0.2 $rev] } {
18
+ # 1.1.1.1 is the base of vendor branches, usually. *.0.y
19
+ # is the base of regular branches where nothing is on the
20
+ # branch yet, only its root is marked. Everything else is
21
+ # noteworthy for now.
22
+ puts $f/$rev/$tag
23
+ }
24
+ }
25
+
26
+ set root [revroot $rev]
27
+ lappend bra [list $date($root) $tag $f $rev]
28
+ }
29
+}
30
+
31
+proc ::vc::cvs::ws::branch::revroot {rev} {
32
+ return [join [lrange [split $rev .] 0 end-2] .]
33
+}
34
+
35
+
36
+ # ! Files in a branch can appear only after their root revision
37
+ # exists. This can be checked against the time of the cset which
38
+ # is our base. Branches which have no files yet can be eliminated
39
+ # from consideration.
40
+
41
+ # ! All files noted by the base cset as added/modified have to be
42
+ # in the branch root. Branches which do not have such a file can
43
+ # be eliminated from consideration.
44
+
45
+ # ! The versions of the added/modified files in the base have
46
+ # match the versions in the branch root. In the sense that they
47
+ # have to be equal or sucessors. The later implies identity in the
48
+ # upper parts (only the last 2 parts are relevant), and equal
49
+ # length.
50
+
51
+ # This gives us the branch, and, due to the time information a
52
+ # signature for the root.
53
+
54
+ #? Can search for the root based on this signature fail ?
55
+ # Yes. Because the signature may contain files which were not
56
+ # actually yet in the root, despite being able to. And which were
57
+ # not modified by the base, so the check 2 above still passes.
58
+
59
+ # -> Search for the full signature first, then drop the youngest
60
+ # files, search again until match. Check the result against the
61
+ # base, that all needed files are present.
62
+
63
+ # However - Can search for the root based on the cset data (needed
64
+ # files). Gives us another set of candidate roots. Intersect!
65
+
66
+
67
+proc ::vc::cvs::ws::branch::find {csvalue} {
68
+ array set cs $csvalue
69
+
70
+ #variable bra
71
+ #puts ___________________________________________
72
+ #puts [join [lsort -index 0 [lsort -index 1 $bra]] \n]
73
+
74
+ Signatures bd [TimeRelevant $cs(date)]
75
+ DropIncomplete bd [concat $cs(added) $cs(changed)]
76
+
77
+ #puts ___________________________________________
78
+ #parray bd
79
+
80
+ if {[array size bd] < 1} {
81
+ puts "NO BRANCH"
82
+ # Deal how?
83
+ # - Abort
84
+ # - Ignore this changeset and try the next one
85
+ # (Which has higher probability of not matching as it might
86
+ # be the successor in the branch to this cset and not a base).
87
+ puts ""
88
+ parray cs
89
+ exit
90
+ } elseif {[array size bd] > 1} {
91
+
92
+ # While we might have found several tag they may all refer to
93
+ # the same set of files. If that is so we consider them
94
+ # identical and take one as representative of all.
95
+
96
+ set su {}
97
+ foreach {t s} [array get bd] {
98
+ lappend su [DictSort $s]
99
+ }
100
+ if {[llength [lsort -unique $su]] > 1} {
101
+ puts "AMBIGOUS. The following branches match:"
102
+ # Deal how? S.a.
103
+ puts \t[join [array names bd] \n\t]
104
+ puts ""
105
+ parray cs
106
+ exit
107
+ }
108
+ # Fall through ...
109
+ }
110
+
111
+ set tg [lindex [array names bd] 0]
112
+ set rs [RootOf $bd($tg)]
113
+
114
+ #puts "BRANCH = $tg"
115
+ #puts "ROOTSG = $rs"
116
+
117
+ return [list $tg $rs]
118
+}
119
+
120
+
121
+proc ::vc::cvs::ws::branch::has {ts needed} {
122
+ #variable bra
123
+ #puts ___________________________________________
124
+ #puts [join [lsort -index 0 [lsort -index 1 $bra]] \n]
125
+
126
+ Signatures bd [TimeRelevant $ts]
127
+ DropIncomplete bd $needed
128
+
129
+ #puts ___________________________________________
130
+ #parray bd
131
+
132
+ if {[array size bd] < 1} {
133
+ puts "NO BRANCH"
134
+ # Deal how?
135
+ # - Abort
136
+ # - Ignore this changeset and try the next one
137
+ # (Which has higher probability of not matching as it might
138
+ # be the successor in the branch to this cset and not a base).
139
+ exit
140
+ } elseif {[array size bd] > 1} {
141
+ puts "AMBIGOUS. Following branches match:"
142
+ # Deal how? S.a.
143
+ puts \t[join [array names bd] \n\t]
144
+ exit
145
+ }
146
+
147
+ set tg [lindex [array names bd] 0]
148
+
149
+ #puts "BRANCH = $tg"
150
+
151
+ return $tg
152
+}
153
+
154
+
155
+
156
+proc ::vc::cvs::ws::branch::RootOf {dict} {
157
+ set res {}
158
+ foreach {f r} $dict {
159
+ lappend res $f [revroot $r]
160
+ }
161
+ return $res
162
+}
163
+
164
+proc ::vc::cvs::ws::branch::DictSort {dict} {
165
+ array set a $dict
166
+ set r {}
167
+ foreach k [lsort [array names a]] {
168
+ lappend r $k $a($k)
169
+ }
170
+ return $r
171
+}
172
+
173
+proc ::vc::cvs::ws::branch::DropIncomplete {bv needed} {
174
+ upvar 1 $bv bdata
175
+
176
+ # Check the needed files against the branch signature. If files
177
+ # are missing or not of a matching version drop the branch from
178
+ # further consideration.
179
+
180
+ foreach {tag sig} [array get bdata] {
181
+ array set rev $sig
182
+ foreach {file rv} $needed {
183
+ if {![info exists rev($file)] || ![successor $rv $rev($file)]} {
184
+ # file in cset is not in the branch or is present, but
185
+ # not proper version (different lengths, not matching
186
+ # in upper 0..end-2 parts, not equal|successor).
187
+ unset bdata($tag)
188
+ break
189
+ }
190
+ continue
191
+ }
192
+ unset rev
193
+ }
194
+ return
195
+}
196
+
197
+proc ::vc::cvs::ws::branch::successor {ra rb} {
198
+ # a successor-of b ?
199
+
200
+ set la [split $ra .]
201
+ set lb [split $rb .]
202
+ if {
203
+ ([llength $la] != [llength $lb]) ||
204
+ ([lrange $la 0 end-2] ne [lrange $lb 0 end-2]) ||
205
+ ([package vcompare $ra $rb] < 0)
206
+ } {
207
+ return 0
208
+ } else {
209
+ return 1
210
+ }
211
+}
212
+
213
+proc ::vc::cvs::ws::branch::Signatures {bv deflist} {
214
+ upvar 1 $bv bdata
215
+ # Sort branch data by symbolic name for the upcoming checks, and
216
+ # generate file revision signatures.
217
+
218
+ array set bdata {}
219
+ foreach item $deflist {
220
+ # item = timestamp tag file revision
221
+ foreach {__ tag file rev} $item break
222
+ lappend bdata($tag) $file $rev
223
+ }
224
+
225
+ #puts ___________________________________________
226
+ #parray bdata
227
+
228
+ return
229
+}
230
+
231
+proc ::vc::cvs::ws::branch::TimeRelevant {date} {
232
+ variable bra
233
+
234
+ # Retrieve the branch data which definitely comes before (in time)
235
+ # the candidate cset. Only this set is relevant to further checks
236
+ # and filters.
237
+
238
+ set res {}
239
+ foreach item $bra {
240
+ # item = timestamp tag file revision
241
+ # 0 1 2 3
242
+ if {[package vcompare [lindex $item 0] $date] > 0} continue
243
+ lappend res $item
244
+ }
245
+
246
+ #puts ___________________________________________
247
+ #puts [join [lsort -index 0 [lsort -index 1 $res]] \n]
248
+ return $res
249
+}
250
+
251
+
252
+namespace eval ::vc::cvs::ws::branch {
253
+ vari # in upper 0..end-2 parts, not equal|successor).
254
+ unset bdata($tag)
255
+ break
256
+ }
257
+ continue
258
+ }
259
+ unset rev
260
+ }
261
+ return
262
+}
263
+
264
+proc ::vc::cvs::ws::branch::successor {ra rb} {
265
+ # a successor-of b ?
266
+
267
+ set la [split $ra .]
268
+ set lb [split $rb .]
269
+ if {
270
+ ([llength $la] != [llength $lb]) ||
271
+ ([lrange $la 0 end-2] ne [lrange $lb 0 end-2]) ||
272
+ ([package vcompare $ra $rb] < 0)
273
+ } {
274
+ return 0
275
+ } else {
276
+ return 1
277
+ }
278
+}
279
+
280
+proc ::vc::cvs::ws::branch::rootSuccessor {ra rb} {
281
+ # a root-successor-of b ? (<=> b root version of a ?)
282
+
283
+ if {$rb eq [revroot $ra]} {
284
+ return 1
285
+ } else {
286
+ return 0
287
+ }
288
+}
289
+
290
+proc ::vc::cvs::ws::branch::Signatures {bv deflist} {
291
+ upvar 1 $bv bdata
292
+ # Sort branch data by symbolic name for the upcoming checks, and
293
+ # generate file revision signatures.
294
+
295
+ array set bdata {}
296
+ foreach item $deflist {
297
+ # item = timestamp tag file revision
298
+ foreach {__ tag file rev} $item break
299
+ lappend bdata($tag) $file $rev
300
+ }
301
+
302
+ #puts ___________________________________________
303
+ #parray bdata
304
+
305
+ return
306
+}
307
+
308
+proc ::vc::cvs::ws::branch::TimeRelevant {date} {
309
+ variable bra
310
+
311
+ # Retrieve the branch data which definitely comes before (in time)
312
+ # the candidate cset. Only this set is relevant to further checks
313
+ # and filters.
314
+
315
+ set res {}
316
+ foreach item $bra {
317
+ # item = timestamp tag file revision
318
+ # 0 1 2 3
319
+ if {[package vcompare [lindex $item 0] $date] > 0} continue
320
+ lappend res $item
321
+ }
322
+
323
+ #puts ___________________________________________
324
+ #puts [join [lsort -index 0 [lsort -index 1 $res]] \n]
325
+ return $res
326
+}
327
+
328
+
329
+namespace eval ::vc::cvs::ws::branch {
330
+ variable bra {}
331
+
332
+ namespace export def find successor rootSuccessor revroot has
333
+}
334
+
335
+package provide vc::cvs::ws::branch 1.0
336
+return
337
+
338
+
339
+
340
+
341
+ # Queries ...
342
+ # - Get set of files and revs for branch B
--- a/tools/lib/cvs_branch.tcl
+++ b/tools/lib/cvs_branch.tcl
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/tools/lib/cvs_branch.tcl
+++ b/tools/lib/cvs_branch.tcl
@@ -0,0 +1,342 @@
1
2
3 namespace eval ::vc::cvs::ws::branch {}
4
5 # Trivial storage of all branch data as a rectangular table. We can
6 # think up a better suited storage system later, when we know what
7 # type of queries are made to this module.
8
9 proc ::vc::cvs::ws::branch::def {f dv deflist} {
10 upvar 1 $dv date
11 variable bra
12 foreach {tag rev} $deflist {
13 # ignore non-branch tags
14 if {[llength [split $rev .]] < 4} continue
15
16 if 0 {
17 if { ($rev ne "1.1.1.1") && ![string match *.0.2 $rev] } {
18 # 1.1.1.1 is the base of vendor branches, usually. *.0.y
19 # is the base of regular branches where nothing is on the
20 # branch yet, only its root is marked. Everything else is
21 # noteworthy for now.
22 puts $f/$rev/$tag
23 }
24 }
25
26 set root [revroot $rev]
27 lappend bra [list $date($root) $tag $f $rev]
28 }
29 }
30
31 proc ::vc::cvs::ws::branch::revroot {rev} {
32 return [join [lrange [split $rev .] 0 end-2] .]
33 }
34
35
36 # ! Files in a branch can appear only after their root revision
37 # exists. This can be checked against the time of the cset which
38 # is our base. Branches which have no files yet can be eliminated
39 # from consideration.
40
41 # ! All files noted by the base cset as added/modified have to be
42 # in the branch root. Branches which do not have such a file can
43 # be eliminated from consideration.
44
45 # ! The versions of the added/modified files in the base have
46 # match the versions in the branch root. In the sense that they
47 # have to be equal or sucessors. The later implies identity in the
48 # upper parts (only the last 2 parts are relevant), and equal
49 # length.
50
51 # This gives us the branch, and, due to the time information a
52 # signature for the root.
53
54 #? Can search for the root based on this signature fail ?
55 # Yes. Because the signature may contain files which were not
56 # actually yet in the root, despite being able to. And which were
57 # not modified by the base, so the check 2 above still passes.
58
59 # -> Search for the full signature first, then drop the youngest
60 # files, search again until match. Check the result against the
61 # base, that all needed files are present.
62
63 # However - Can search for the root based on the cset data (needed
64 # files). Gives us another set of candidate roots. Intersect!
65
66
67 proc ::vc::cvs::ws::branch::find {csvalue} {
68 array set cs $csvalue
69
70 #variable bra
71 #puts ___________________________________________
72 #puts [join [lsort -index 0 [lsort -index 1 $bra]] \n]
73
74 Signatures bd [TimeRelevant $cs(date)]
75 DropIncomplete bd [concat $cs(added) $cs(changed)]
76
77 #puts ___________________________________________
78 #parray bd
79
80 if {[array size bd] < 1} {
81 puts "NO BRANCH"
82 # Deal how?
83 # - Abort
84 # - Ignore this changeset and try the next one
85 # (Which has higher probability of not matching as it might
86 # be the successor in the branch to this cset and not a base).
87 puts ""
88 parray cs
89 exit
90 } elseif {[array size bd] > 1} {
91
92 # While we might have found several tag they may all refer to
93 # the same set of files. If that is so we consider them
94 # identical and take one as representative of all.
95
96 set su {}
97 foreach {t s} [array get bd] {
98 lappend su [DictSort $s]
99 }
100 if {[llength [lsort -unique $su]] > 1} {
101 puts "AMBIGOUS. The following branches match:"
102 # Deal how? S.a.
103 puts \t[join [array names bd] \n\t]
104 puts ""
105 parray cs
106 exit
107 }
108 # Fall through ...
109 }
110
111 set tg [lindex [array names bd] 0]
112 set rs [RootOf $bd($tg)]
113
114 #puts "BRANCH = $tg"
115 #puts "ROOTSG = $rs"
116
117 return [list $tg $rs]
118 }
119
120
121 proc ::vc::cvs::ws::branch::has {ts needed} {
122 #variable bra
123 #puts ___________________________________________
124 #puts [join [lsort -index 0 [lsort -index 1 $bra]] \n]
125
126 Signatures bd [TimeRelevant $ts]
127 DropIncomplete bd $needed
128
129 #puts ___________________________________________
130 #parray bd
131
132 if {[array size bd] < 1} {
133 puts "NO BRANCH"
134 # Deal how?
135 # - Abort
136 # - Ignore this changeset and try the next one
137 # (Which has higher probability of not matching as it might
138 # be the successor in the branch to this cset and not a base).
139 exit
140 } elseif {[array size bd] > 1} {
141 puts "AMBIGOUS. Following branches match:"
142 # Deal how? S.a.
143 puts \t[join [array names bd] \n\t]
144 exit
145 }
146
147 set tg [lindex [array names bd] 0]
148
149 #puts "BRANCH = $tg"
150
151 return $tg
152 }
153
154
155
156 proc ::vc::cvs::ws::branch::RootOf {dict} {
157 set res {}
158 foreach {f r} $dict {
159 lappend res $f [revroot $r]
160 }
161 return $res
162 }
163
164 proc ::vc::cvs::ws::branch::DictSort {dict} {
165 array set a $dict
166 set r {}
167 foreach k [lsort [array names a]] {
168 lappend r $k $a($k)
169 }
170 return $r
171 }
172
173 proc ::vc::cvs::ws::branch::DropIncomplete {bv needed} {
174 upvar 1 $bv bdata
175
176 # Check the needed files against the branch signature. If files
177 # are missing or not of a matching version drop the branch from
178 # further consideration.
179
180 foreach {tag sig} [array get bdata] {
181 array set rev $sig
182 foreach {file rv} $needed {
183 if {![info exists rev($file)] || ![successor $rv $rev($file)]} {
184 # file in cset is not in the branch or is present, but
185 # not proper version (different lengths, not matching
186 # in upper 0..end-2 parts, not equal|successor).
187 unset bdata($tag)
188 break
189 }
190 continue
191 }
192 unset rev
193 }
194 return
195 }
196
197 proc ::vc::cvs::ws::branch::successor {ra rb} {
198 # a successor-of b ?
199
200 set la [split $ra .]
201 set lb [split $rb .]
202 if {
203 ([llength $la] != [llength $lb]) ||
204 ([lrange $la 0 end-2] ne [lrange $lb 0 end-2]) ||
205 ([package vcompare $ra $rb] < 0)
206 } {
207 return 0
208 } else {
209 return 1
210 }
211 }
212
213 proc ::vc::cvs::ws::branch::Signatures {bv deflist} {
214 upvar 1 $bv bdata
215 # Sort branch data by symbolic name for the upcoming checks, and
216 # generate file revision signatures.
217
218 array set bdata {}
219 foreach item $deflist {
220 # item = timestamp tag file revision
221 foreach {__ tag file rev} $item break
222 lappend bdata($tag) $file $rev
223 }
224
225 #puts ___________________________________________
226 #parray bdata
227
228 return
229 }
230
231 proc ::vc::cvs::ws::branch::TimeRelevant {date} {
232 variable bra
233
234 # Retrieve the branch data which definitely comes before (in time)
235 # the candidate cset. Only this set is relevant to further checks
236 # and filters.
237
238 set res {}
239 foreach item $bra {
240 # item = timestamp tag file revision
241 # 0 1 2 3
242 if {[package vcompare [lindex $item 0] $date] > 0} continue
243 lappend res $item
244 }
245
246 #puts ___________________________________________
247 #puts [join [lsort -index 0 [lsort -index 1 $res]] \n]
248 return $res
249 }
250
251
252 namespace eval ::vc::cvs::ws::branch {
253 vari # in upper 0..end-2 parts, not equal|successor).
254 unset bdata($tag)
255 break
256 }
257 continue
258 }
259 unset rev
260 }
261 return
262 }
263
264 proc ::vc::cvs::ws::branch::successor {ra rb} {
265 # a successor-of b ?
266
267 set la [split $ra .]
268 set lb [split $rb .]
269 if {
270 ([llength $la] != [llength $lb]) ||
271 ([lrange $la 0 end-2] ne [lrange $lb 0 end-2]) ||
272 ([package vcompare $ra $rb] < 0)
273 } {
274 return 0
275 } else {
276 return 1
277 }
278 }
279
280 proc ::vc::cvs::ws::branch::rootSuccessor {ra rb} {
281 # a root-successor-of b ? (<=> b root version of a ?)
282
283 if {$rb eq [revroot $ra]} {
284 return 1
285 } else {
286 return 0
287 }
288 }
289
290 proc ::vc::cvs::ws::branch::Signatures {bv deflist} {
291 upvar 1 $bv bdata
292 # Sort branch data by symbolic name for the upcoming checks, and
293 # generate file revision signatures.
294
295 array set bdata {}
296 foreach item $deflist {
297 # item = timestamp tag file revision
298 foreach {__ tag file rev} $item break
299 lappend bdata($tag) $file $rev
300 }
301
302 #puts ___________________________________________
303 #parray bdata
304
305 return
306 }
307
308 proc ::vc::cvs::ws::branch::TimeRelevant {date} {
309 variable bra
310
311 # Retrieve the branch data which definitely comes before (in time)
312 # the candidate cset. Only this set is relevant to further checks
313 # and filters.
314
315 set res {}
316 foreach item $bra {
317 # item = timestamp tag file revision
318 # 0 1 2 3
319 if {[package vcompare [lindex $item 0] $date] > 0} continue
320 lappend res $item
321 }
322
323 #puts ___________________________________________
324 #puts [join [lsort -index 0 [lsort -index 1 $res]] \n]
325 return $res
326 }
327
328
329 namespace eval ::vc::cvs::ws::branch {
330 variable bra {}
331
332 namespace export def find successor rootSuccessor revroot has
333 }
334
335 package provide vc::cvs::ws::branch 1.0
336 return
337
338
339
340
341 # Queries ...
342 # - Get set of files and revs for branch B
--- tools/lib/cvs_csets.tcl
+++ tools/lib/cvs_csets.tcl
@@ -3,12 +3,16 @@
33
44
# -----------------------------------------------------------------------------
55
# Requirements
66
77
package require Tcl 8.4
8
+package require vc::cvs::ws::sig ; # Changeset file/rev signatures
89
910
namespace eval ::vc::cvs::ws::csets::Current {}
11
+namespace eval ::vc::cvs::ws::csets::sig {
12
+ namespace import ::vc::cvs::ws::sig::*
13
+}
1014
1115
# -----------------------------------------------------------------------------
1216
# API
1317
1418
# vc::cvs::ws::csets::init - Initialize accumulator
@@ -45,10 +49,18 @@
4549
proc ::vc::cvs::ws::csets::get {id} {
4650
variable csets
4751
return $csets($id)
4852
}
4953
54
+
55
+proc ::vc::cvs::ws::csets::DUMP {id} {
56
+ puts /${id}/_________________
57
+ array set cs [get $id]
58
+ parray cs
59
+ return
60
+}
61
+
5062
proc ::vc::cvs::ws::csets::num {} {
5163
variable csets
5264
return [array size csets]
5365
}
5466
@@ -59,18 +71,27 @@
5971
}
6072
6173
proc ::vc::cvs::ws::csets::setParentOf {id parent} {
6274
variable csets
6375
lappend csets($id) parent $parent
76
+
77
+ array set cs $csets($id)
78
+ sig::def $id $parent $cs(added) $cs(changed) $cs(removed)
6479
return
6580
}
6681
6782
proc ::vc::cvs::ws::csets::parentOf {id} {
6883
variable csets
6984
array set cs $csets($id)
7085
return $cs(parent)
7186
}
87
+
88
+proc ::vc::cvs::ws::csets::sameBranch {id parent tag} {
89
+ variable csets
90
+ array set cs $csets($id)
91
+ return [sig::next $parent $cs(added) $cs(changed) $cs(removed) $tag $cs(date)]
92
+}
7293
7394
# -----------------------------------------------------------------------------
7495
# Internal helper commands: Changeset inspection and construction.
7596
7697
proc ::vc::cvs::ws::csets::Save {data} {
@@ -215,13 +236,13 @@
215236
variable changed {} ; # file -> revision of modified files.
216237
variable files
217238
array set files {} ; # file -> revision
218239
}
219240
220
- namespace export init add done get num isTrunk setParentOf parentOf
241
+ namespace export init add done get num isTrunk setParentOf parentOf sameBranch
221242
}
222243
223244
# -----------------------------------------------------------------------------
224245
# Ready
225246
226247
package provide vc::cvs::ws::csets 1.0
227248
return
228249
229250
ADDED tools/lib/cvs_sig.tcl
--- tools/lib/cvs_csets.tcl
+++ tools/lib/cvs_csets.tcl
@@ -3,12 +3,16 @@
3
4 # -----------------------------------------------------------------------------
5 # Requirements
6
7 package require Tcl 8.4
 
8
9 namespace eval ::vc::cvs::ws::csets::Current {}
 
 
 
10
11 # -----------------------------------------------------------------------------
12 # API
13
14 # vc::cvs::ws::csets::init - Initialize accumulator
@@ -45,10 +49,18 @@
45 proc ::vc::cvs::ws::csets::get {id} {
46 variable csets
47 return $csets($id)
48 }
49
 
 
 
 
 
 
 
 
50 proc ::vc::cvs::ws::csets::num {} {
51 variable csets
52 return [array size csets]
53 }
54
@@ -59,18 +71,27 @@
59 }
60
61 proc ::vc::cvs::ws::csets::setParentOf {id parent} {
62 variable csets
63 lappend csets($id) parent $parent
 
 
 
64 return
65 }
66
67 proc ::vc::cvs::ws::csets::parentOf {id} {
68 variable csets
69 array set cs $csets($id)
70 return $cs(parent)
71 }
 
 
 
 
 
 
72
73 # -----------------------------------------------------------------------------
74 # Internal helper commands: Changeset inspection and construction.
75
76 proc ::vc::cvs::ws::csets::Save {data} {
@@ -215,13 +236,13 @@
215 variable changed {} ; # file -> revision of modified files.
216 variable files
217 array set files {} ; # file -> revision
218 }
219
220 namespace export init add done get num isTrunk setParentOf parentOf
221 }
222
223 # -----------------------------------------------------------------------------
224 # Ready
225
226 package provide vc::cvs::ws::csets 1.0
227 return
228
229 DDED tools/lib/cvs_sig.tcl
--- tools/lib/cvs_csets.tcl
+++ tools/lib/cvs_csets.tcl
@@ -3,12 +3,16 @@
3
4 # -----------------------------------------------------------------------------
5 # Requirements
6
7 package require Tcl 8.4
8 package require vc::cvs::ws::sig ; # Changeset file/rev signatures
9
10 namespace eval ::vc::cvs::ws::csets::Current {}
11 namespace eval ::vc::cvs::ws::csets::sig {
12 namespace import ::vc::cvs::ws::sig::*
13 }
14
15 # -----------------------------------------------------------------------------
16 # API
17
18 # vc::cvs::ws::csets::init - Initialize accumulator
@@ -45,10 +49,18 @@
49 proc ::vc::cvs::ws::csets::get {id} {
50 variable csets
51 return $csets($id)
52 }
53
54
55 proc ::vc::cvs::ws::csets::DUMP {id} {
56 puts /${id}/_________________
57 array set cs [get $id]
58 parray cs
59 return
60 }
61
62 proc ::vc::cvs::ws::csets::num {} {
63 variable csets
64 return [array size csets]
65 }
66
@@ -59,18 +71,27 @@
71 }
72
73 proc ::vc::cvs::ws::csets::setParentOf {id parent} {
74 variable csets
75 lappend csets($id) parent $parent
76
77 array set cs $csets($id)
78 sig::def $id $parent $cs(added) $cs(changed) $cs(removed)
79 return
80 }
81
82 proc ::vc::cvs::ws::csets::parentOf {id} {
83 variable csets
84 array set cs $csets($id)
85 return $cs(parent)
86 }
87
88 proc ::vc::cvs::ws::csets::sameBranch {id parent tag} {
89 variable csets
90 array set cs $csets($id)
91 return [sig::next $parent $cs(added) $cs(changed) $cs(removed) $tag $cs(date)]
92 }
93
94 # -----------------------------------------------------------------------------
95 # Internal helper commands: Changeset inspection and construction.
96
97 proc ::vc::cvs::ws::csets::Save {data} {
@@ -215,13 +236,13 @@
236 variable changed {} ; # file -> revision of modified files.
237 variable files
238 array set files {} ; # file -> revision
239 }
240
241 namespace export init add done get num isTrunk setParentOf parentOf sameBranch
242 }
243
244 # -----------------------------------------------------------------------------
245 # Ready
246
247 package provide vc::cvs::ws::csets 1.0
248 return
249
250 DDED tools/lib/cvs_sig.tcl
--- a/tools/lib/cvs_sig.tcl
+++ b/tools/lib/cvs_sig.tcl
@@ -0,0 +1,67 @@
1
+
2
+package require struct::set
3
+package require vc::cvs::ws::branch
4
+
5
+namespace eval ::vc::cvs::ws::sig::branch {
6
+ namespace import ::vc::cvs::ws::branch::*
7
+}
8
+
9
+# Save the mapping from changesets to file/rev signatures, and further
10
+# remember all the csets a specific file/rev combination belongs to.
11
+
12
+proc ::vc::cvs::ws::sig::def {id parent added changed removed} {
13
+ variable sig
14
+ variable csl
15
+
16
+ array set new $sig($parent)
17
+ array set new $added
18
+ array set new $changed
19
+ foreach {f r} $removed {catch {unset new($f)}}
20
+ set sig($id) [DictSort [array get new]]
21
+
22
+ foreach {f r} [array get new] {
23
+ lappend csl($f,$r) $id
24
+ }
25
+ return
26
+}
27
+
28
+proc ::vc::cvs::ws::sig::next {id added changed removed tag ts} {
29
+ variable sig
30
+ array set rev $sig($id)
31
+
32
+ foreach {f r} [concat $changed $removed] {
33
+ if {![info exists rev($f)] || r $rev($f)]} continu$r $rev($f)]*($res)/$return 0
34
+ }
35
+ }
36
+return 0
37
+ }
38
+ }
39
+ return 1
40
+}
41
+
42
+
43
+proc ::vc::cvs::ws::sig::find {id sig} {
44
+ set cslist [Cut $id [Find $sig]]
45
+
46
+ if {[llength $cslist] < 1} {
47
+ puts "NO ROOT"
48
+ # Deal how?
49
+ # - Abort
50
+ # - Ignore this changeset and try the next one
51
+ # (Which has higher probability of not matching as it might
52
+ # be the successor in the branch to this cset and not a base).
53
+ exit
54
+ } elseif {[llength $cslist] > 1} {
55
+ puts "AMBIGOUS. Following csets match root requirements:"
56
+ # Deal how? S.a.
57
+ puts \t[join $cslist \n\t]
58
+ exit
59
+ }
60
+
61
+ set r [lindex $cslist 0]
62
+ #puts "ROOT = $r"
63
+ return $r
64
+}
65
+
66
+proc ::vc::cvs::ws::sig::Cut {id cslist} {
67
+ # Changesets
--- a/tools/lib/cvs_sig.tcl
+++ b/tools/lib/cvs_sig.tcl
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/tools/lib/cvs_sig.tcl
+++ b/tools/lib/cvs_sig.tcl
@@ -0,0 +1,67 @@
1
2 package require struct::set
3 package require vc::cvs::ws::branch
4
5 namespace eval ::vc::cvs::ws::sig::branch {
6 namespace import ::vc::cvs::ws::branch::*
7 }
8
9 # Save the mapping from changesets to file/rev signatures, and further
10 # remember all the csets a specific file/rev combination belongs to.
11
12 proc ::vc::cvs::ws::sig::def {id parent added changed removed} {
13 variable sig
14 variable csl
15
16 array set new $sig($parent)
17 array set new $added
18 array set new $changed
19 foreach {f r} $removed {catch {unset new($f)}}
20 set sig($id) [DictSort [array get new]]
21
22 foreach {f r} [array get new] {
23 lappend csl($f,$r) $id
24 }
25 return
26 }
27
28 proc ::vc::cvs::ws::sig::next {id added changed removed tag ts} {
29 variable sig
30 array set rev $sig($id)
31
32 foreach {f r} [concat $changed $removed] {
33 if {![info exists rev($f)] || r $rev($f)]} continu$r $rev($f)]*($res)/$return 0
34 }
35 }
36 return 0
37 }
38 }
39 return 1
40 }
41
42
43 proc ::vc::cvs::ws::sig::find {id sig} {
44 set cslist [Cut $id [Find $sig]]
45
46 if {[llength $cslist] < 1} {
47 puts "NO ROOT"
48 # Deal how?
49 # - Abort
50 # - Ignore this changeset and try the next one
51 # (Which has higher probability of not matching as it might
52 # be the successor in the branch to this cset and not a base).
53 exit
54 } elseif {[llength $cslist] > 1} {
55 puts "AMBIGOUS. Following csets match root requirements:"
56 # Deal how? S.a.
57 puts \t[join $cslist \n\t]
58 exit
59 }
60
61 set r [lindex $cslist 0]
62 #puts "ROOT = $r"
63 return $r
64 }
65
66 proc ::vc::cvs::ws::sig::Cut {id cslist} {
67 # Changesets
--- tools/lib/pkgIndex.tcl
+++ tools/lib/pkgIndex.tcl
@@ -3,10 +3,12 @@
33
package ifneeded vc::cvs::cmd 1.0 [list source [file join $dir cvs_cmd.tcl]]
44
package ifneeded vc::cvs::ws 1.0 [list source [file join $dir cvs.tcl]]
55
package ifneeded vc::cvs::ws::files 1.0 [list source [file join $dir cvs_files.tcl]]
66
package ifneeded vc::cvs::ws::timeline 1.0 [list source [file join $dir cvs_timeline.tcl]]
77
package ifneeded vc::cvs::ws::csets 1.0 [list source [file join $dir cvs_csets.tcl]]
8
+package ifneeded vc::cvs::ws::branch 1.0 [list source [file join $dir cvs_branch.tcl]]
9
+package ifneeded vc::cvs::ws::sig 1.0 [list source [file join $dir cvs_sig.tcl]]
810
package ifneeded vc::fossil::cmd 1.0 [list source [file join $dir fossil_cmd.tcl]]
911
package ifneeded vc::fossil::ws 1.0 [list source [file join $dir fossil.tcl]]
1012
package ifneeded vc::fossil::import::cvs 1.0 [list source [file join $dir importcvs.tcl]]
1113
package ifneeded vc::fossil::import::stats 1.0 [list source [file join $dir import_statistics.tcl]]
1214
package ifneeded vc::fossil::import::map 1.0 [list source [file join $dir import_map.tcl]]
1315
--- tools/lib/pkgIndex.tcl
+++ tools/lib/pkgIndex.tcl
@@ -3,10 +3,12 @@
3 package ifneeded vc::cvs::cmd 1.0 [list source [file join $dir cvs_cmd.tcl]]
4 package ifneeded vc::cvs::ws 1.0 [list source [file join $dir cvs.tcl]]
5 package ifneeded vc::cvs::ws::files 1.0 [list source [file join $dir cvs_files.tcl]]
6 package ifneeded vc::cvs::ws::timeline 1.0 [list source [file join $dir cvs_timeline.tcl]]
7 package ifneeded vc::cvs::ws::csets 1.0 [list source [file join $dir cvs_csets.tcl]]
 
 
8 package ifneeded vc::fossil::cmd 1.0 [list source [file join $dir fossil_cmd.tcl]]
9 package ifneeded vc::fossil::ws 1.0 [list source [file join $dir fossil.tcl]]
10 package ifneeded vc::fossil::import::cvs 1.0 [list source [file join $dir importcvs.tcl]]
11 package ifneeded vc::fossil::import::stats 1.0 [list source [file join $dir import_statistics.tcl]]
12 package ifneeded vc::fossil::import::map 1.0 [list source [file join $dir import_map.tcl]]
13
--- tools/lib/pkgIndex.tcl
+++ tools/lib/pkgIndex.tcl
@@ -3,10 +3,12 @@
3 package ifneeded vc::cvs::cmd 1.0 [list source [file join $dir cvs_cmd.tcl]]
4 package ifneeded vc::cvs::ws 1.0 [list source [file join $dir cvs.tcl]]
5 package ifneeded vc::cvs::ws::files 1.0 [list source [file join $dir cvs_files.tcl]]
6 package ifneeded vc::cvs::ws::timeline 1.0 [list source [file join $dir cvs_timeline.tcl]]
7 package ifneeded vc::cvs::ws::csets 1.0 [list source [file join $dir cvs_csets.tcl]]
8 package ifneeded vc::cvs::ws::branch 1.0 [list source [file join $dir cvs_branch.tcl]]
9 package ifneeded vc::cvs::ws::sig 1.0 [list source [file join $dir cvs_sig.tcl]]
10 package ifneeded vc::fossil::cmd 1.0 [list source [file join $dir fossil_cmd.tcl]]
11 package ifneeded vc::fossil::ws 1.0 [list source [file join $dir fossil.tcl]]
12 package ifneeded vc::fossil::import::cvs 1.0 [list source [file join $dir importcvs.tcl]]
13 package ifneeded vc::fossil::import::stats 1.0 [list source [file join $dir import_statistics.tcl]]
14 package ifneeded vc::fossil::import::map 1.0 [list source [file join $dir import_map.tcl]]
15

Keyboard Shortcuts

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