Fossil SCM

Completed pass 7, breaking dependency cycles over symbol changesets. Moved the bulk of the cycle breaker code into its own class as it was common to the passes 6 and 7, and updated the two passes accordingly. Added code to load the changeset counter from the state to start properly.

aku 2007-11-16 04:17 trunk
Commit 770a9b576affade7f180463397cdbf638607ddf9
--- a/tools/cvs2fossil/lib/c2f_cyclebreaker.tcl
+++ b/tools/cvs2fossil/lib/c2f_cyclebreaker.tcl
@@ -0,0 +1,180 @@
1
+ }
2
+
3
+ typemethod breakcmd {cmd} {
4
+ ::variable mybreakcmd $cmd
5
+ return
6
+ }
7
+
8
+ # # ## ### ##### ######## #############
9
+
10
+ typemethod dotsto {path} {
11
+ ::variable mydotdestination $path
12
+ return
13
+ }
14
+
15
+ typemethod watch {id} {
16
+ ::variable mywatchids
17
+ lappend mywatchids $id
18
+ }
19
+
20
+ typemethod dot {label changesets} {
21
+ ::variable mydotprefix $label
22
+ ::variable mydotid 0
23
+
24
+ set dg [Setup $changesets 0]
25
+ Mark $dg
26
+ $dg destroy
27
+ return
28
+ }
29
+
30
+ typemethod mark {graph suffix {subgraph {}}} {
31
+ Mark $graph $suffix $subgraph
32
+ return
33
+ }
34
+
35
+ # # ## ### ##### ######## #############
36
+
37
+ typemethod run {label changesetcmd} {
38
+ ::variable myat 0
39
+ ::variable mydotprefix $label
40
+ ::variable mydotid 0
41
+
42
+ # We create a graph of the revision changesets, using the file
43
+ # level dependencies to construct a first approximation of the
44
+ # dependencies at the project level. Then we look for cycles
45
+ # in that graph and break them.
46
+
47
+ # 1. Create nodes for all relevant changesets and a mapping
48
+ # from the revisions to tlogelevant changesets and a mappinggraph topologically. We mark off
49
+ # the nodes which have no predecs. If
50
+ # we find no nodes without predecessors we have a cycle,
51
+ # and work on breaking it.
52
+
53
+ log write 3 cyclebreaker {Traverse changesets}
54
+
55
+ InitializeCanNow sorting the chantivated.
56
+
57
+ ::variable mydowhile {1} }
58
+
59
+ d} {
60
+ ::variable mybreakcmybreakcmd $cmd
61
+ return
62
+ }
63
+
64
+ # # ## ### ##### ######## #############
65
+
66
+ typemethod dotsto {path} {
67
+ ::variable mydotdestination run {# ######## {s ############ typemethte a graph of at
68
+ # level dependencies to construct a first approximation of the
69
+ # dependencies at the project level. Then we look for cycles
70
+ # in that graph and break them.
71
+
72
+ # 1. Create nodes for all relevant changesets and a mappi }
73
+
74
+ # savecmdSaveAndRemove $dg $n
75
+ }clebreaker { BreakCycle $dg [FindCycle $dg]ivated.
76
+
77
+ ::variable mydowhile {dowhile {1} }
78
+
79
+ d} {
80
+ ::variable mybreakcmybreakcmd $cmd
81
+ return
82
+ }dowhile {1} }
83
+
84
+ d} {
85
+ :# ############ typemethod dotsto {path} {
86
+ ::v ::varian
87
+ }
88
+
89
+ # # ### }
90
+
91
+ tymd $cmd
92
+ return
93
+ }
94
+
95
+ # # ## ### ##### ######## #############
96
+
97
+ typemethod dotsto {path} {
98
+ ::variable 0# # ## ### ##### ######## {savedowhile {1} }
99
+
100
+ d} {
101
+ e mydotid 0
102
+
103
+ # We create aid 0
104
+
105
+ # We create a graph of the revision changesets, using the file
106
+ # level dependencies to construct a first approximation of the
107
+ # dependencies at the p 0
108
+ ::variable mydotprefix $label
109
+ ::variable mydotid 0
110
+
111
+ # We create a graph of the revision changesets, using the file
112
+ # level dependencies to construct a first approximation of the
113
+ # dependencies at the project level. Then we look for cycles
114
+ # in that graph and break them.
115
+
116
+ # 1. Create nodes for all relevant changesets and a mapping
117
+ # from the revisions to their changesets/nodes.
118
+
119
+ set changesets [uplevel #0 $changesetcmd]
120
+ set dg [Setup $changesets]
121
+
122
+ # 3. Lastly we iterate the graph topologically. We mark off
123
+ # the nodes which have no predecs. If
124
+ # we find no nodes without predecessors we have a cycle,
125
+ # and work on breaking it.
126
+
127
+ ll relevant changesets and a mappi }
128
+
129
+ # savecmdSaveAndRemove $dg $n
130
+ }clebreaker { BreakCycle $dg [FindCycle $dg]ivated.
131
+
132
+ ::variable mydowhile {1} }
133
+
134
+ d} {
135
+ ::variable mybreakcmybreakcmd $ceakcmd {cmd} {
136
+ ::variable mybreakcmd $cmd
137
+ return
138
+ }
139
+
140
+ # # ## ### }
141
+
142
+ typemethod breakcmd {cmd} {
143
+ ::variable mybreakurn
144
+ }
145
+
146
+ }
147
+
148
+ typemethobottom [lrange $n
149
+ }
150
+
151
+ # # ## ### ##### ######## #############
152
+
153
+ typemethod dotsto {path} {
154
+ ::variable mydotdestination $path
155
+ return
156
+ }
157
+
158
+ typemethod watch {id} {
159
+ ::variable mywatchids
160
+ lappend mywatchids $id
161
+ }
162
+
163
+ typemethod dot {label changesets} {
164
+ ::variable mydotprefix $label
165
+ ::variable mydotid 0
166
+
167
+ set dg [Setup $changesets 0]
168
+ Mark $dg
169
+ $dg destroy
170
+ return
171
+ }
172
+
173
+ typemethod mark {graph suffix {subgraph {}}} {
174
+ Mark $graph $suffix $subgraph
175
+ }
176
+
177
+ typemethod breakcmd atsave end $at $n]
178
+ }
179
+
180
+ incr # ## ### ##### ######variable atbottomsavemethod break
--- a/tools/cvs2fossil/lib/c2f_cyclebreaker.tcl
+++ b/tools/cvs2fossil/lib/c2f_cyclebreaker.tcl
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/tools/cvs2fossil/lib/c2f_cyclebreaker.tcl
+++ b/tools/cvs2fossil/lib/c2f_cyclebreaker.tcl
@@ -0,0 +1,180 @@
1 }
2
3 typemethod breakcmd {cmd} {
4 ::variable mybreakcmd $cmd
5 return
6 }
7
8 # # ## ### ##### ######## #############
9
10 typemethod dotsto {path} {
11 ::variable mydotdestination $path
12 return
13 }
14
15 typemethod watch {id} {
16 ::variable mywatchids
17 lappend mywatchids $id
18 }
19
20 typemethod dot {label changesets} {
21 ::variable mydotprefix $label
22 ::variable mydotid 0
23
24 set dg [Setup $changesets 0]
25 Mark $dg
26 $dg destroy
27 return
28 }
29
30 typemethod mark {graph suffix {subgraph {}}} {
31 Mark $graph $suffix $subgraph
32 return
33 }
34
35 # # ## ### ##### ######## #############
36
37 typemethod run {label changesetcmd} {
38 ::variable myat 0
39 ::variable mydotprefix $label
40 ::variable mydotid 0
41
42 # We create a graph of the revision changesets, using the file
43 # level dependencies to construct a first approximation of the
44 # dependencies at the project level. Then we look for cycles
45 # in that graph and break them.
46
47 # 1. Create nodes for all relevant changesets and a mapping
48 # from the revisions to tlogelevant changesets and a mappinggraph topologically. We mark off
49 # the nodes which have no predecs. If
50 # we find no nodes without predecessors we have a cycle,
51 # and work on breaking it.
52
53 log write 3 cyclebreaker {Traverse changesets}
54
55 InitializeCanNow sorting the chantivated.
56
57 ::variable mydowhile {1} }
58
59 d} {
60 ::variable mybreakcmybreakcmd $cmd
61 return
62 }
63
64 # # ## ### ##### ######## #############
65
66 typemethod dotsto {path} {
67 ::variable mydotdestination run {# ######## {s ############ typemethte a graph of at
68 # level dependencies to construct a first approximation of the
69 # dependencies at the project level. Then we look for cycles
70 # in that graph and break them.
71
72 # 1. Create nodes for all relevant changesets and a mappi }
73
74 # savecmdSaveAndRemove $dg $n
75 }clebreaker { BreakCycle $dg [FindCycle $dg]ivated.
76
77 ::variable mydowhile {dowhile {1} }
78
79 d} {
80 ::variable mybreakcmybreakcmd $cmd
81 return
82 }dowhile {1} }
83
84 d} {
85 :# ############ typemethod dotsto {path} {
86 ::v ::varian
87 }
88
89 # # ### }
90
91 tymd $cmd
92 return
93 }
94
95 # # ## ### ##### ######## #############
96
97 typemethod dotsto {path} {
98 ::variable 0# # ## ### ##### ######## {savedowhile {1} }
99
100 d} {
101 e mydotid 0
102
103 # We create aid 0
104
105 # We create a graph of the revision changesets, using the file
106 # level dependencies to construct a first approximation of the
107 # dependencies at the p 0
108 ::variable mydotprefix $label
109 ::variable mydotid 0
110
111 # We create a graph of the revision changesets, using the file
112 # level dependencies to construct a first approximation of the
113 # dependencies at the project level. Then we look for cycles
114 # in that graph and break them.
115
116 # 1. Create nodes for all relevant changesets and a mapping
117 # from the revisions to their changesets/nodes.
118
119 set changesets [uplevel #0 $changesetcmd]
120 set dg [Setup $changesets]
121
122 # 3. Lastly we iterate the graph topologically. We mark off
123 # the nodes which have no predecs. If
124 # we find no nodes without predecessors we have a cycle,
125 # and work on breaking it.
126
127 ll relevant changesets and a mappi }
128
129 # savecmdSaveAndRemove $dg $n
130 }clebreaker { BreakCycle $dg [FindCycle $dg]ivated.
131
132 ::variable mydowhile {1} }
133
134 d} {
135 ::variable mybreakcmybreakcmd $ceakcmd {cmd} {
136 ::variable mybreakcmd $cmd
137 return
138 }
139
140 # # ## ### }
141
142 typemethod breakcmd {cmd} {
143 ::variable mybreakurn
144 }
145
146 }
147
148 typemethobottom [lrange $n
149 }
150
151 # # ## ### ##### ######## #############
152
153 typemethod dotsto {path} {
154 ::variable mydotdestination $path
155 return
156 }
157
158 typemethod watch {id} {
159 ::variable mywatchids
160 lappend mywatchids $id
161 }
162
163 typemethod dot {label changesets} {
164 ::variable mydotprefix $label
165 ::variable mydotid 0
166
167 set dg [Setup $changesets 0]
168 Mark $dg
169 $dg destroy
170 return
171 }
172
173 typemethod mark {graph suffix {subgraph {}}} {
174 Mark $graph $suffix $subgraph
175 }
176
177 typemethod breakcmd atsave end $at $n]
178 }
179
180 incr # ## ### ##### ######variable atbottomsavemethod break
--- tools/cvs2fossil/lib/c2f_pbreakrcycle.tcl
+++ tools/cvs2fossil/lib/c2f_pbreakrcycle.tcl
@@ -10,23 +10,23 @@
1010
# history and logs, available at http://fossil-scm.hwaci.com/fossil
1111
# # ## ### ##### ######## ############# #####################
1212
1313
## Pass VI. This pass goes over the set of revision based changesets
1414
## and breaks all dependency cycles they may be in. We need a
15
-## dependency tree.
15
+## dependency tree. Identical to pass VII, except for the selection of
16
+## the changesets.
1617
1718
# # ## ### ##### ######## ############# #####################
1819
## Requirements
1920
2021
package require Tcl 8.4 ; # Required runtime.
2122
package require snit ; # OO system.
22
-package require struct::graph ; # Graph handling.
2323
package require struct::list ; # Higher order list operations.
2424
package require vc::tools::log ; # User feedback.
25
+package require vc::fossil::import::cvs::cyclebreaker ; # Breaking dependency cycles.
2526
package require vc::fossil::import::cvs::state ; # State storage.
2627
package require vc::fossil::import::cvs::project::rev ; # Project level changesets
27
-package require vc::fossil::import::cvs::project::revlink ; # Cycle links.
2828
2929
# # ## ### ##### ######## ############# #####################
3030
## Register the pass with the management
3131
3232
vc::fossil::import::cvs::pass define \
@@ -50,18 +50,20 @@
5050
cid INTEGER NOT NULL REFERENCES changeset,
5151
pos INTEGER NOT NULL,
5252
UNIQUE (cid),
5353
UNIQUE (pos)
5454
}
55
-
5655
return
5756
}
5857
5958
typemethod load {} {
6059
# Pass manager interface. Executed to load data computed by
6160
# this pass into memory when this pass is skipped instead of
6261
# executed.
62
+
63
+ state reading changeset
64
+ project::rev loadcounter
6365
return
6466
}
6567
6668
typemethod run {} {
6769
# Pass manager interface. Executed to perform the
@@ -69,68 +71,15 @@
6971
7072
state reading revision
7173
state reading changeset
7274
state reading csrevision
7375
74
- # We create a graph of the revision changesets, using the file
75
- # level dependencies to construct a first approximation of
76
- # them at the project level. Then look for cycles in that
77
- # graph and break them.
78
-
79
- # 1. Create nodes for all relevant changesets and a mapping
80
- # from the revisions to their changesets/nodes.
81
-
82
- log write 3 breakrcycle {Creating changeset graph, filling with nodes}
83
-
84
- set dg [struct::graph dg]
85
-
86
- state transaction {
87
- foreach cset [project::rev all] {
88
- if {[$cset bysymbol]} continue
89
- dg node insert $cset
90
- dg node set $cset timerange [$cset timerange]
91
- }
92
- }
93
-
94
- # 2. Find for all relevant changeset their revisions and their
95
- # dependencies. Map the latter back to changesets and
96
- # construct the corresponding arcs.
97
-
98
- log write 3 breakrcycle {Setting up node dependencies}
99
-
100
- state transaction {
101
- foreach cset [project::rev all] {
102
- if {[$cset bysymbol]} continue
103
- foreach succ [$cset successors] {
104
- # Changesets may have dependencies outside of the
105
- # chosen set. These are ignored
106
- if {![dg node exists $succ]} continue
107
- dg arc insert $cset $succ
108
- }
109
- }
110
- }
111
-
112
- # 3. Lastly we iterate the graph topologically. We mark off
113
- # the nodes which have no predecessors, in order from
114
- # oldest to youngest, saving and removing dependencies. If
115
- # we find no nodes without predecessors we have a cycle,
116
- # and work on breaking it.
117
-
118
- log write 3 breakrcycle {Computing changeset order, breaking cycles}
119
-
120
- InitializeCandidates $dg
121
- state transaction {
122
- while {1} {
123
- while {[WithoutPredecessor $dg n]} {
124
- SaveAndRemove $dg $n
125
- }
126
- if {![llength [dg nodes]]} break
127
- BreakCycle $dg [FindCycle $dg]
128
- InitializeCandidates $dg
129
- }
130
- }
131
-
76
+ state transaction {
77
+ cyclebreaker run [struct::list filter [project::rev all] \
78
+ [myproc IsByRevision]] \
79
+ [myproc SaveOrder]
80
+ }
13281
return
13382
}
13483
13584
typemethod discard {} {
13685
# Pass manager interface. Executed for all passes after the
@@ -142,172 +91,23 @@
14291
}
14392
14493
# # ## ### ##### ######## #############
14594
## Internal methods
14695
147
- # Instead of searching the whole graph for the degree-0 nodes in
148
- # each iteration we compute the list once to start, and then only
149
- # update it incrementally based on the outgoing neighbours of the
150
- # node chosen for commit.
151
-
152
- proc InitializeCandidates {dg} {
153
- # bottom = list (list (node, range min, range max))
154
- ::variable bottom
155
- foreach n [$dg nodes] {
156
- if {[$dg node degree -in $n]} continue
157
- lappend bottom [linsert [$dg node get $n timerange] 0 $n]
158
- }
159
- set bottom [lsort -index 1 -integer [lsort -index 2 -integer $bottom]]
160
- return
161
- }
162
-
163
- proc WithoutPredecessor {dg nv} {
164
- ::variable bottom
165
-
166
- upvar 1 $nv n
167
- if {![llength $bottom]} { return 0 }
168
-
169
- set n [lindex [lindex $bottom 0] 0]
170
- set bottom [lrange $bottom 1 end]
171
- set changed 0
172
-
173
- # Update list of nodes without predecessor, based on the
174
- # outgoing neighbours of the chosen node. This should be
175
- # faster than iterating of the whole set of nodes, finding all
176
- # without predecessors, sorting them by time, etc. pp.
177
- foreach out [$dg nodes -out $n] {
178
- if {[$dg node degree -in $out] > 1} continue
179
- # Degree-1 neighbour, will have no predecessors after the
180
- # removal of n. Put on the list.
181
- lappend bottom [linsert [$dg node get $out timerange] 0 $out]
182
- set changed 1
183
- }
184
- if {$changed} {
185
- set bottom [lsort -index 1 -integer [lsort -index 2 -integer $bottom]]
186
- }
187
-
188
- # We do not delete the node immediately, to allow the Save
189
- # procedure to save the dependencies as well (encoded in the
190
- # arcs).
191
- return 1
192
- }
193
-
194
- proc SaveAndRemove {dg n} {
195
- ::variable at
196
- set cid [$n id]
96
+ proc IsByRevision {cset} { $cset byrevision }
97
+
98
+ proc SaveOrder {at cset} {
99
+ set cid [$cset id]
197100
198101
log write 4 breakrcycle "Comitting @ $at: <$cid>"
199102
state run {
200103
INSERT INTO csorder (cid, pos)
201104
VALUES ($cid, $at)
202105
}
203106
# TODO: Write the project level changeset dependencies as well.
204
- incr at
205
- $dg node delete $n
206
- return
207
- }
208
-
209
- proc FindCycle {dg} {
210
- # This procedure is run if and only the graph is not empty and
211
- # all nodes have predecessors. This means that each node is
212
- # either part of a cycle or (indirectly) depending on a node
213
- # in a cycle. We can start at an arbitrary node, follow its
214
- # incoming edges to its predecessors until we see a node a
215
- # second time. That node closes the cycle and the beginning is
216
- # its first occurence. Note that we can choose an arbitrary
217
- # predecessor of each node as well, we do not have to search.
218
-
219
- # We record for each node the index of the first appearance in
220
- # the path, making it easy at the end to cut the cycle from
221
- # it.
222
-
223
- # Choose arbitrary node to start our search at.
224
- set start [lindex [$dg nodes] 0]
225
-
226
- # Initialize state, path of seen nodes, and when seen.
227
- set path {}
228
- array set seen {}
229
-
230
- while {1} {
231
- # Stop searching when we have seen the current node
232
- # already, the circle has been closed.
233
- if {[info exists seen($start)]} break
234
- lappend path $start
235
- set seen($start) [expr {[llength $path]-1}]
236
- # Choose arbitrary predecessor
237
- set start [lindex [$dg nodes -in $start] 0]
238
- }
239
-
240
- return [struct::list reverse [lrange $path $seen($start) end]]
241
- }
242
-
243
- proc ID {cset} { return "<[$cset id]>" }
244
-
245
- proc BreakCycle {dg cycle} {
246
- # The cycle we have gotten is broken by breaking apart one or
247
- # more of the changesets in the cycle. This causes us to
248
- # create one or more changesets which are to be committed,
249
- # added to the graph, etc. pp.
250
-
251
- set cprint [join [struct::list map $cycle [myproc ID]] { }]
252
-
253
- lappend cycle [lindex $cycle 0] [lindex $cycle 1]
254
- set bestlink {}
255
- set bestnode {}
256
-
257
- foreach \
258
- prev [lrange $cycle 0 end-2] \
259
- cset [lrange $cycle 1 end-1] \
260
- next [lrange $cycle 2 end] {
261
-
262
- # Each triple PREV -> CSET -> NEXT of changesets, a
263
- # 'link' in the cycle, is analysed and the best
264
- # location where to at least weaken the cycle is
265
- # chosen for further processing.
266
-
267
- set link [project::revlink %AUTO% $prev $cset $next]
268
- if {$bestlink eq ""} {
269
- set bestlink $link
270
- set bestnode $cset
271
- } elseif {[$link betterthan $bestlink]} {
272
- $bestlink destroy
273
- set bestlink $link
274
- set bestnode $cset
275
- } else {
276
- $link destroy
277
- }
278
- }
279
-
280
- log write 5 breakrcycle "Breaking cycle ($cprint) by splitting changeset <[$bestnode id]>"
281
-
282
- set newcsets [$bestlink break]
283
- $bestlink destroy
284
-
285
- # At this point the old changeset (BESTNODE) is gone
286
- # already. We remove it from the graph as well and then enter
287
- # the fragments generated for it.
288
-
289
- $dg node delete $bestnode
290
-
291
- foreach cset $newcsets {
292
- $dg node insert $cset
293
- $dg node set $cset timerange [$cset timerange]
294
- }
295
-
296
- foreach cset $newcsets {
297
- foreach succ [$cset successors] {
298
- # Changesets may have dependencies outside of the
299
- # chosen set. These are ignored
300
- if {![dg node exists $succ]} continue
301
- $dg arc insert $cset $succ
302
- }
303
- }
304
- return
305
- }
306
-
307
- typevariable at 0 ; # Counter for commit ids for the changesets.
308
- typevariable bottom {} ; # List of candidate nodes for committing.
107
+ return
108
+ }
309109
310110
# # ## ### ##### ######## #############
311111
## Configuration
312112
313113
pragma -hasinstances no ; # singleton
@@ -318,14 +118,14 @@
318118
}
319119
320120
namespace eval ::vc::fossil::import::cvs::pass {
321121
namespace export breakrcycle
322122
namespace eval breakrcycle {
123
+ namespace import ::vc::fossil::import::cvs::cyclebreaker
323124
namespace import ::vc::fossil::import::cvs::state
324125
namespace eval project {
325126
namespace import ::vc::fossil::import::cvs::project::rev
326
- namespace import ::vc::fossil::import::cvs::project::revlink
327127
}
328128
namespace import ::vc::tools::log
329129
log register breakrcycle
330130
}
331131
}
332132
--- tools/cvs2fossil/lib/c2f_pbreakrcycle.tcl
+++ tools/cvs2fossil/lib/c2f_pbreakrcycle.tcl
@@ -10,23 +10,23 @@
10 # history and logs, available at http://fossil-scm.hwaci.com/fossil
11 # # ## ### ##### ######## ############# #####################
12
13 ## Pass VI. This pass goes over the set of revision based changesets
14 ## and breaks all dependency cycles they may be in. We need a
15 ## dependency tree.
 
16
17 # # ## ### ##### ######## ############# #####################
18 ## Requirements
19
20 package require Tcl 8.4 ; # Required runtime.
21 package require snit ; # OO system.
22 package require struct::graph ; # Graph handling.
23 package require struct::list ; # Higher order list operations.
24 package require vc::tools::log ; # User feedback.
 
25 package require vc::fossil::import::cvs::state ; # State storage.
26 package require vc::fossil::import::cvs::project::rev ; # Project level changesets
27 package require vc::fossil::import::cvs::project::revlink ; # Cycle links.
28
29 # # ## ### ##### ######## ############# #####################
30 ## Register the pass with the management
31
32 vc::fossil::import::cvs::pass define \
@@ -50,18 +50,20 @@
50 cid INTEGER NOT NULL REFERENCES changeset,
51 pos INTEGER NOT NULL,
52 UNIQUE (cid),
53 UNIQUE (pos)
54 }
55
56 return
57 }
58
59 typemethod load {} {
60 # Pass manager interface. Executed to load data computed by
61 # this pass into memory when this pass is skipped instead of
62 # executed.
 
 
 
63 return
64 }
65
66 typemethod run {} {
67 # Pass manager interface. Executed to perform the
@@ -69,68 +71,15 @@
69
70 state reading revision
71 state reading changeset
72 state reading csrevision
73
74 # We create a graph of the revision changesets, using the file
75 # level dependencies to construct a first approximation of
76 # them at the project level. Then look for cycles in that
77 # graph and break them.
78
79 # 1. Create nodes for all relevant changesets and a mapping
80 # from the revisions to their changesets/nodes.
81
82 log write 3 breakrcycle {Creating changeset graph, filling with nodes}
83
84 set dg [struct::graph dg]
85
86 state transaction {
87 foreach cset [project::rev all] {
88 if {[$cset bysymbol]} continue
89 dg node insert $cset
90 dg node set $cset timerange [$cset timerange]
91 }
92 }
93
94 # 2. Find for all relevant changeset their revisions and their
95 # dependencies. Map the latter back to changesets and
96 # construct the corresponding arcs.
97
98 log write 3 breakrcycle {Setting up node dependencies}
99
100 state transaction {
101 foreach cset [project::rev all] {
102 if {[$cset bysymbol]} continue
103 foreach succ [$cset successors] {
104 # Changesets may have dependencies outside of the
105 # chosen set. These are ignored
106 if {![dg node exists $succ]} continue
107 dg arc insert $cset $succ
108 }
109 }
110 }
111
112 # 3. Lastly we iterate the graph topologically. We mark off
113 # the nodes which have no predecessors, in order from
114 # oldest to youngest, saving and removing dependencies. If
115 # we find no nodes without predecessors we have a cycle,
116 # and work on breaking it.
117
118 log write 3 breakrcycle {Computing changeset order, breaking cycles}
119
120 InitializeCandidates $dg
121 state transaction {
122 while {1} {
123 while {[WithoutPredecessor $dg n]} {
124 SaveAndRemove $dg $n
125 }
126 if {![llength [dg nodes]]} break
127 BreakCycle $dg [FindCycle $dg]
128 InitializeCandidates $dg
129 }
130 }
131
132 return
133 }
134
135 typemethod discard {} {
136 # Pass manager interface. Executed for all passes after the
@@ -142,172 +91,23 @@
142 }
143
144 # # ## ### ##### ######## #############
145 ## Internal methods
146
147 # Instead of searching the whole graph for the degree-0 nodes in
148 # each iteration we compute the list once to start, and then only
149 # update it incrementally based on the outgoing neighbours of the
150 # node chosen for commit.
151
152 proc InitializeCandidates {dg} {
153 # bottom = list (list (node, range min, range max))
154 ::variable bottom
155 foreach n [$dg nodes] {
156 if {[$dg node degree -in $n]} continue
157 lappend bottom [linsert [$dg node get $n timerange] 0 $n]
158 }
159 set bottom [lsort -index 1 -integer [lsort -index 2 -integer $bottom]]
160 return
161 }
162
163 proc WithoutPredecessor {dg nv} {
164 ::variable bottom
165
166 upvar 1 $nv n
167 if {![llength $bottom]} { return 0 }
168
169 set n [lindex [lindex $bottom 0] 0]
170 set bottom [lrange $bottom 1 end]
171 set changed 0
172
173 # Update list of nodes without predecessor, based on the
174 # outgoing neighbours of the chosen node. This should be
175 # faster than iterating of the whole set of nodes, finding all
176 # without predecessors, sorting them by time, etc. pp.
177 foreach out [$dg nodes -out $n] {
178 if {[$dg node degree -in $out] > 1} continue
179 # Degree-1 neighbour, will have no predecessors after the
180 # removal of n. Put on the list.
181 lappend bottom [linsert [$dg node get $out timerange] 0 $out]
182 set changed 1
183 }
184 if {$changed} {
185 set bottom [lsort -index 1 -integer [lsort -index 2 -integer $bottom]]
186 }
187
188 # We do not delete the node immediately, to allow the Save
189 # procedure to save the dependencies as well (encoded in the
190 # arcs).
191 return 1
192 }
193
194 proc SaveAndRemove {dg n} {
195 ::variable at
196 set cid [$n id]
197
198 log write 4 breakrcycle "Comitting @ $at: <$cid>"
199 state run {
200 INSERT INTO csorder (cid, pos)
201 VALUES ($cid, $at)
202 }
203 # TODO: Write the project level changeset dependencies as well.
204 incr at
205 $dg node delete $n
206 return
207 }
208
209 proc FindCycle {dg} {
210 # This procedure is run if and only the graph is not empty and
211 # all nodes have predecessors. This means that each node is
212 # either part of a cycle or (indirectly) depending on a node
213 # in a cycle. We can start at an arbitrary node, follow its
214 # incoming edges to its predecessors until we see a node a
215 # second time. That node closes the cycle and the beginning is
216 # its first occurence. Note that we can choose an arbitrary
217 # predecessor of each node as well, we do not have to search.
218
219 # We record for each node the index of the first appearance in
220 # the path, making it easy at the end to cut the cycle from
221 # it.
222
223 # Choose arbitrary node to start our search at.
224 set start [lindex [$dg nodes] 0]
225
226 # Initialize state, path of seen nodes, and when seen.
227 set path {}
228 array set seen {}
229
230 while {1} {
231 # Stop searching when we have seen the current node
232 # already, the circle has been closed.
233 if {[info exists seen($start)]} break
234 lappend path $start
235 set seen($start) [expr {[llength $path]-1}]
236 # Choose arbitrary predecessor
237 set start [lindex [$dg nodes -in $start] 0]
238 }
239
240 return [struct::list reverse [lrange $path $seen($start) end]]
241 }
242
243 proc ID {cset} { return "<[$cset id]>" }
244
245 proc BreakCycle {dg cycle} {
246 # The cycle we have gotten is broken by breaking apart one or
247 # more of the changesets in the cycle. This causes us to
248 # create one or more changesets which are to be committed,
249 # added to the graph, etc. pp.
250
251 set cprint [join [struct::list map $cycle [myproc ID]] { }]
252
253 lappend cycle [lindex $cycle 0] [lindex $cycle 1]
254 set bestlink {}
255 set bestnode {}
256
257 foreach \
258 prev [lrange $cycle 0 end-2] \
259 cset [lrange $cycle 1 end-1] \
260 next [lrange $cycle 2 end] {
261
262 # Each triple PREV -> CSET -> NEXT of changesets, a
263 # 'link' in the cycle, is analysed and the best
264 # location where to at least weaken the cycle is
265 # chosen for further processing.
266
267 set link [project::revlink %AUTO% $prev $cset $next]
268 if {$bestlink eq ""} {
269 set bestlink $link
270 set bestnode $cset
271 } elseif {[$link betterthan $bestlink]} {
272 $bestlink destroy
273 set bestlink $link
274 set bestnode $cset
275 } else {
276 $link destroy
277 }
278 }
279
280 log write 5 breakrcycle "Breaking cycle ($cprint) by splitting changeset <[$bestnode id]>"
281
282 set newcsets [$bestlink break]
283 $bestlink destroy
284
285 # At this point the old changeset (BESTNODE) is gone
286 # already. We remove it from the graph as well and then enter
287 # the fragments generated for it.
288
289 $dg node delete $bestnode
290
291 foreach cset $newcsets {
292 $dg node insert $cset
293 $dg node set $cset timerange [$cset timerange]
294 }
295
296 foreach cset $newcsets {
297 foreach succ [$cset successors] {
298 # Changesets may have dependencies outside of the
299 # chosen set. These are ignored
300 if {![dg node exists $succ]} continue
301 $dg arc insert $cset $succ
302 }
303 }
304 return
305 }
306
307 typevariable at 0 ; # Counter for commit ids for the changesets.
308 typevariable bottom {} ; # List of candidate nodes for committing.
309
310 # # ## ### ##### ######## #############
311 ## Configuration
312
313 pragma -hasinstances no ; # singleton
@@ -318,14 +118,14 @@
318 }
319
320 namespace eval ::vc::fossil::import::cvs::pass {
321 namespace export breakrcycle
322 namespace eval breakrcycle {
 
323 namespace import ::vc::fossil::import::cvs::state
324 namespace eval project {
325 namespace import ::vc::fossil::import::cvs::project::rev
326 namespace import ::vc::fossil::import::cvs::project::revlink
327 }
328 namespace import ::vc::tools::log
329 log register breakrcycle
330 }
331 }
332
--- tools/cvs2fossil/lib/c2f_pbreakrcycle.tcl
+++ tools/cvs2fossil/lib/c2f_pbreakrcycle.tcl
@@ -10,23 +10,23 @@
10 # history and logs, available at http://fossil-scm.hwaci.com/fossil
11 # # ## ### ##### ######## ############# #####################
12
13 ## Pass VI. This pass goes over the set of revision based changesets
14 ## and breaks all dependency cycles they may be in. We need a
15 ## dependency tree. Identical to pass VII, except for the selection of
16 ## the changesets.
17
18 # # ## ### ##### ######## ############# #####################
19 ## Requirements
20
21 package require Tcl 8.4 ; # Required runtime.
22 package require snit ; # OO system.
 
23 package require struct::list ; # Higher order list operations.
24 package require vc::tools::log ; # User feedback.
25 package require vc::fossil::import::cvs::cyclebreaker ; # Breaking dependency cycles.
26 package require vc::fossil::import::cvs::state ; # State storage.
27 package require vc::fossil::import::cvs::project::rev ; # Project level changesets
 
28
29 # # ## ### ##### ######## ############# #####################
30 ## Register the pass with the management
31
32 vc::fossil::import::cvs::pass define \
@@ -50,18 +50,20 @@
50 cid INTEGER NOT NULL REFERENCES changeset,
51 pos INTEGER NOT NULL,
52 UNIQUE (cid),
53 UNIQUE (pos)
54 }
 
55 return
56 }
57
58 typemethod load {} {
59 # Pass manager interface. Executed to load data computed by
60 # this pass into memory when this pass is skipped instead of
61 # executed.
62
63 state reading changeset
64 project::rev loadcounter
65 return
66 }
67
68 typemethod run {} {
69 # Pass manager interface. Executed to perform the
@@ -69,68 +71,15 @@
71
72 state reading revision
73 state reading changeset
74 state reading csrevision
75
76 state transaction {
77 cyclebreaker run [struct::list filter [project::rev all] \
78 [myproc IsByRevision]] \
79 [myproc SaveOrder]
80 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81 return
82 }
83
84 typemethod discard {} {
85 # Pass manager interface. Executed for all passes after the
@@ -142,172 +91,23 @@
91 }
92
93 # # ## ### ##### ######## #############
94 ## Internal methods
95
96 proc IsByRevision {cset} { $cset byrevision }
97
98 proc SaveOrder {at cset} {
99 set cid [$cset id]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
101 log write 4 breakrcycle "Comitting @ $at: <$cid>"
102 state run {
103 INSERT INTO csorder (cid, pos)
104 VALUES ($cid, $at)
105 }
106 # TODO: Write the project level changeset dependencies as well.
107 return
108 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
110 # # ## ### ##### ######## #############
111 ## Configuration
112
113 pragma -hasinstances no ; # singleton
@@ -318,14 +118,14 @@
118 }
119
120 namespace eval ::vc::fossil::import::cvs::pass {
121 namespace export breakrcycle
122 namespace eval breakrcycle {
123 namespace import ::vc::fossil::import::cvs::cyclebreaker
124 namespace import ::vc::fossil::import::cvs::state
125 namespace eval project {
126 namespace import ::vc::fossil::import::cvs::project::rev
 
127 }
128 namespace import ::vc::tools::log
129 log register breakrcycle
130 }
131 }
132
--- tools/cvs2fossil/lib/c2f_pbreakscycle.tcl
+++ tools/cvs2fossil/lib/c2f_pbreakscycle.tcl
@@ -10,19 +10,22 @@
1010
# history and logs, available at http://fossil-scm.hwaci.com/fossil
1111
# # ## ### ##### ######## ############# #####################
1212
1313
## Pass VII. This pass goes over the set of symbol based changesets
1414
## and breaks all dependency cycles they may be in. We need a
15
-## dependency tree.
15
+## dependency tree. Identical to pass VI, except for the selection of
16
+## the changesets.
1617
1718
# # ## ### ##### ######## ############# #####################
1819
## Requirements
1920
2021
package require Tcl 8.4 ; # Required runtime.
2122
package require snit ; # OO system.
22
-package require vc::tools::log ; # User feedback.
23
+package require struct::list ; # Higher order list operations.
24
+package require vc::fossil::import::cvs::cyclebreaker ; # Breaking dependency cycles.
2325
package require vc::fossil::import::cvs::state ; # State storage.
26
+package require vc::fossil::import::cvs::project::rev ; # Project level changesets
2427
2528
# # ## ### ##### ######## ############# #####################
2629
## Register the pass with the management
2730
2831
vc::fossil::import::cvs::pass define \
@@ -51,10 +54,19 @@
5154
}
5255
5356
typemethod run {} {
5457
# Pass manager interface. Executed to perform the
5558
# functionality of the pass.
59
+
60
+ state reading revision
61
+ state reading changeset
62
+ state reading csrevision
63
+
64
+ state transaction {
65
+ cyclebreaker run [struct::list filter [project::rev all] \
66
+ [myproc IsBySymbol]]
67
+ }
5668
return
5769
}
5870
5971
typemethod discard {} {
6072
# Pass manager interface. Executed for all passes after the
@@ -63,10 +75,12 @@
6375
return
6476
}
6577
6678
# # ## ### ##### ######## #############
6779
## Internal methods
80
+
81
+ proc IsBySymbol {cset} { $cset bysymbol }
6882
6983
# # ## ### ##### ######## #############
7084
## Configuration
7185
7286
pragma -hasinstances no ; # singleton
@@ -77,16 +91,18 @@
7791
}
7892
7993
namespace eval ::vc::fossil::import::cvs::pass {
8094
namespace export breakscycle
8195
namespace eval breakscycle {
96
+ namespace import ::vc::fossil::import::cvs::cyclebreaker
8297
namespace import ::vc::fossil::import::cvs::state
83
- namespace import ::vc::tools::log
84
- log register breakscycle
98
+ namespace eval project {
99
+ namespace import ::vc::fossil::import::cvs::project::rev
100
+ }
85101
}
86102
}
87103
88104
# # ## ### ##### ######## ############# #####################
89105
## Ready
90106
91107
package provide vc::fossil::import::cvs::pass::breakscycle 1.0
92108
return
93109
--- tools/cvs2fossil/lib/c2f_pbreakscycle.tcl
+++ tools/cvs2fossil/lib/c2f_pbreakscycle.tcl
@@ -10,19 +10,22 @@
10 # history and logs, available at http://fossil-scm.hwaci.com/fossil
11 # # ## ### ##### ######## ############# #####################
12
13 ## Pass VII. This pass goes over the set of symbol based changesets
14 ## and breaks all dependency cycles they may be in. We need a
15 ## dependency tree.
 
16
17 # # ## ### ##### ######## ############# #####################
18 ## Requirements
19
20 package require Tcl 8.4 ; # Required runtime.
21 package require snit ; # OO system.
22 package require vc::tools::log ; # User feedback.
 
23 package require vc::fossil::import::cvs::state ; # State storage.
 
24
25 # # ## ### ##### ######## ############# #####################
26 ## Register the pass with the management
27
28 vc::fossil::import::cvs::pass define \
@@ -51,10 +54,19 @@
51 }
52
53 typemethod run {} {
54 # Pass manager interface. Executed to perform the
55 # functionality of the pass.
 
 
 
 
 
 
 
 
 
56 return
57 }
58
59 typemethod discard {} {
60 # Pass manager interface. Executed for all passes after the
@@ -63,10 +75,12 @@
63 return
64 }
65
66 # # ## ### ##### ######## #############
67 ## Internal methods
 
 
68
69 # # ## ### ##### ######## #############
70 ## Configuration
71
72 pragma -hasinstances no ; # singleton
@@ -77,16 +91,18 @@
77 }
78
79 namespace eval ::vc::fossil::import::cvs::pass {
80 namespace export breakscycle
81 namespace eval breakscycle {
 
82 namespace import ::vc::fossil::import::cvs::state
83 namespace import ::vc::tools::log
84 log register breakscycle
 
85 }
86 }
87
88 # # ## ### ##### ######## ############# #####################
89 ## Ready
90
91 package provide vc::fossil::import::cvs::pass::breakscycle 1.0
92 return
93
--- tools/cvs2fossil/lib/c2f_pbreakscycle.tcl
+++ tools/cvs2fossil/lib/c2f_pbreakscycle.tcl
@@ -10,19 +10,22 @@
10 # history and logs, available at http://fossil-scm.hwaci.com/fossil
11 # # ## ### ##### ######## ############# #####################
12
13 ## Pass VII. This pass goes over the set of symbol based changesets
14 ## and breaks all dependency cycles they may be in. We need a
15 ## dependency tree. Identical to pass VI, except for the selection of
16 ## the changesets.
17
18 # # ## ### ##### ######## ############# #####################
19 ## Requirements
20
21 package require Tcl 8.4 ; # Required runtime.
22 package require snit ; # OO system.
23 package require struct::list ; # Higher order list operations.
24 package require vc::fossil::import::cvs::cyclebreaker ; # Breaking dependency cycles.
25 package require vc::fossil::import::cvs::state ; # State storage.
26 package require vc::fossil::import::cvs::project::rev ; # Project level changesets
27
28 # # ## ### ##### ######## ############# #####################
29 ## Register the pass with the management
30
31 vc::fossil::import::cvs::pass define \
@@ -51,10 +54,19 @@
54 }
55
56 typemethod run {} {
57 # Pass manager interface. Executed to perform the
58 # functionality of the pass.
59
60 state reading revision
61 state reading changeset
62 state reading csrevision
63
64 state transaction {
65 cyclebreaker run [struct::list filter [project::rev all] \
66 [myproc IsBySymbol]]
67 }
68 return
69 }
70
71 typemethod discard {} {
72 # Pass manager interface. Executed for all passes after the
@@ -63,10 +75,12 @@
75 return
76 }
77
78 # # ## ### ##### ######## #############
79 ## Internal methods
80
81 proc IsBySymbol {cset} { $cset bysymbol }
82
83 # # ## ### ##### ######## #############
84 ## Configuration
85
86 pragma -hasinstances no ; # singleton
@@ -77,16 +91,18 @@
91 }
92
93 namespace eval ::vc::fossil::import::cvs::pass {
94 namespace export breakscycle
95 namespace eval breakscycle {
96 namespace import ::vc::fossil::import::cvs::cyclebreaker
97 namespace import ::vc::fossil::import::cvs::state
98 namespace eval project {
99 namespace import ::vc::fossil::import::cvs::project::rev
100 }
101 }
102 }
103
104 # # ## ### ##### ######## ############# #####################
105 ## Ready
106
107 package provide vc::fossil::import::cvs::pass::breakscycle 1.0
108 return
109
--- tools/cvs2fossil/lib/c2f_prev.tcl
+++ tools/cvs2fossil/lib/c2f_prev.tcl
@@ -274,19 +274,27 @@
274274
# once.
275275
276276
# # ## ### ##### ######## #############
277277
## Internal methods
278278
279
- typevariable mycounter 0 ; # Id counter for csets.
279
+ typevariable mycounter 0 ; # Id counter for csets. Last id used.
280280
typevariable mycstype -array {} ; # Map cstypes to persistent ids.
281281
282282
typemethod getcstypes {} {
283283
foreach {tid name} [state run {
284284
SELECT tid, name FROM cstype;
285285
}] { set mycstype($name) $tid }
286286
return
287287
}
288
+
289
+ typemethod loadcounter {} {
290
+ # Initialize the counter from the state
291
+ set mycounter [lindex [state run {
292
+ SELECT MAX(cid) FROM changeset
293
+ }] 0]
294
+ return
295
+ }
288296
289297
proc PullInternalSuccessorRevisions {dv revisions} {
290298
upvar 1 $dv dependencies
291299
set theset ('[join $revisions {','}]')
292300
293301
--- tools/cvs2fossil/lib/c2f_prev.tcl
+++ tools/cvs2fossil/lib/c2f_prev.tcl
@@ -274,19 +274,27 @@
274 # once.
275
276 # # ## ### ##### ######## #############
277 ## Internal methods
278
279 typevariable mycounter 0 ; # Id counter for csets.
280 typevariable mycstype -array {} ; # Map cstypes to persistent ids.
281
282 typemethod getcstypes {} {
283 foreach {tid name} [state run {
284 SELECT tid, name FROM cstype;
285 }] { set mycstype($name) $tid }
286 return
287 }
 
 
 
 
 
 
 
 
288
289 proc PullInternalSuccessorRevisions {dv revisions} {
290 upvar 1 $dv dependencies
291 set theset ('[join $revisions {','}]')
292
293
--- tools/cvs2fossil/lib/c2f_prev.tcl
+++ tools/cvs2fossil/lib/c2f_prev.tcl
@@ -274,19 +274,27 @@
274 # once.
275
276 # # ## ### ##### ######## #############
277 ## Internal methods
278
279 typevariable mycounter 0 ; # Id counter for csets. Last id used.
280 typevariable mycstype -array {} ; # Map cstypes to persistent ids.
281
282 typemethod getcstypes {} {
283 foreach {tid name} [state run {
284 SELECT tid, name FROM cstype;
285 }] { set mycstype($name) $tid }
286 return
287 }
288
289 typemethod loadcounter {} {
290 # Initialize the counter from the state
291 set mycounter [lindex [state run {
292 SELECT MAX(cid) FROM changeset
293 }] 0]
294 return
295 }
296
297 proc PullInternalSuccessorRevisions {dv revisions} {
298 upvar 1 $dv dependencies
299 set theset ('[join $revisions {','}]')
300
301
--- tools/cvs2fossil/lib/pkgIndex.tcl
+++ tools/cvs2fossil/lib/pkgIndex.tcl
@@ -17,10 +17,11 @@
1717
package ifneeded vc::fossil::import::cvs::pass::collsym 1.0 [list source [file join $dir c2f_pcollsym.tcl]]
1818
package ifneeded vc::fossil::import::cvs::pass::filtersym 1.0 [list source [file join $dir c2f_pfiltersym.tcl]]
1919
package ifneeded vc::fossil::import::cvs::pass::initcsets 1.0 [list source [file join $dir c2f_pinitcsets.tcl]]
2020
package ifneeded vc::fossil::import::cvs::pass::breakrcycle 1.0 [list source [file join $dir c2f_pbreakrcycle.tcl]]
2121
package ifneeded vc::fossil::import::cvs::pass::breakscycle 1.0 [list source [file join $dir c2f_pbreakscycle.tcl]]
22
+package ifneeded vc::fossil::import::cvs::cyclebreaker 1.0 [list source [file join $dir c2f_cyclebreaker.tcl]]
2223
package ifneeded vc::fossil::import::cvs::project 1.0 [list source [file join $dir c2f_project.tcl]]
2324
package ifneeded vc::fossil::import::cvs::project::lodmgr 1.0 [list source [file join $dir c2f_plodmgr.tcl]]
2425
package ifneeded vc::fossil::import::cvs::project::rev 1.0 [list source [file join $dir c2f_prev.tcl]]
2526
package ifneeded vc::fossil::import::cvs::project::revlink 1.0 [list source [file join $dir c2f_prevlink.tcl]]
2627
package ifneeded vc::fossil::import::cvs::project::sym 1.0 [list source [file join $dir c2f_psym.tcl]]
2728
--- tools/cvs2fossil/lib/pkgIndex.tcl
+++ tools/cvs2fossil/lib/pkgIndex.tcl
@@ -17,10 +17,11 @@
17 package ifneeded vc::fossil::import::cvs::pass::collsym 1.0 [list source [file join $dir c2f_pcollsym.tcl]]
18 package ifneeded vc::fossil::import::cvs::pass::filtersym 1.0 [list source [file join $dir c2f_pfiltersym.tcl]]
19 package ifneeded vc::fossil::import::cvs::pass::initcsets 1.0 [list source [file join $dir c2f_pinitcsets.tcl]]
20 package ifneeded vc::fossil::import::cvs::pass::breakrcycle 1.0 [list source [file join $dir c2f_pbreakrcycle.tcl]]
21 package ifneeded vc::fossil::import::cvs::pass::breakscycle 1.0 [list source [file join $dir c2f_pbreakscycle.tcl]]
 
22 package ifneeded vc::fossil::import::cvs::project 1.0 [list source [file join $dir c2f_project.tcl]]
23 package ifneeded vc::fossil::import::cvs::project::lodmgr 1.0 [list source [file join $dir c2f_plodmgr.tcl]]
24 package ifneeded vc::fossil::import::cvs::project::rev 1.0 [list source [file join $dir c2f_prev.tcl]]
25 package ifneeded vc::fossil::import::cvs::project::revlink 1.0 [list source [file join $dir c2f_prevlink.tcl]]
26 package ifneeded vc::fossil::import::cvs::project::sym 1.0 [list source [file join $dir c2f_psym.tcl]]
27
--- tools/cvs2fossil/lib/pkgIndex.tcl
+++ tools/cvs2fossil/lib/pkgIndex.tcl
@@ -17,10 +17,11 @@
17 package ifneeded vc::fossil::import::cvs::pass::collsym 1.0 [list source [file join $dir c2f_pcollsym.tcl]]
18 package ifneeded vc::fossil::import::cvs::pass::filtersym 1.0 [list source [file join $dir c2f_pfiltersym.tcl]]
19 package ifneeded vc::fossil::import::cvs::pass::initcsets 1.0 [list source [file join $dir c2f_pinitcsets.tcl]]
20 package ifneeded vc::fossil::import::cvs::pass::breakrcycle 1.0 [list source [file join $dir c2f_pbreakrcycle.tcl]]
21 package ifneeded vc::fossil::import::cvs::pass::breakscycle 1.0 [list source [file join $dir c2f_pbreakscycle.tcl]]
22 package ifneeded vc::fossil::import::cvs::cyclebreaker 1.0 [list source [file join $dir c2f_cyclebreaker.tcl]]
23 package ifneeded vc::fossil::import::cvs::project 1.0 [list source [file join $dir c2f_project.tcl]]
24 package ifneeded vc::fossil::import::cvs::project::lodmgr 1.0 [list source [file join $dir c2f_plodmgr.tcl]]
25 package ifneeded vc::fossil::import::cvs::project::rev 1.0 [list source [file join $dir c2f_prev.tcl]]
26 package ifneeded vc::fossil::import::cvs::project::revlink 1.0 [list source [file join $dir c2f_prevlink.tcl]]
27 package ifneeded vc::fossil::import::cvs::project::sym 1.0 [list source [file join $dir c2f_psym.tcl]]
28

Keyboard Shortcuts

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