Differences From:
File
tools/cvs2fossil/lib/c2f_pinitcsets.tcl
part of check-in
[5f7acef887]
- Completed pass 5, computing the initial set of changesets. Defined persistent structure and filled out the long-existing placeholder class (project::rev).
by
aku on
2007-11-10 07:46:20.
[view]
To:
File
tools/cvs2fossil/lib/c2f_pinitcsets.tcl
part of check-in
[95af789e1f]
- Oops. pass 5 is not complete. Missed the breaking of internal dependencies, this is done in this pass already. Extended pass _2_ and file revisions with code to save the branchchildren (possible dependencies), and pass 5 and changesets with the proper algorithm. From cvs2svn, works, do not truly like it, as it throws away and recomputes a lot of state after each split of a cset. Could update and reuse the state to perform all splits in one go. Will try that next, for now we have a working form in the code base.
by
aku on
2007-11-10 20:40:06.
[view]
@@ -46,8 +46,9 @@
# this pass.
state reading meta
state reading revision
+ state reading revisionbranchchildren
state reading branch
state reading tag
state reading symbol
@@ -110,11 +111,12 @@
# functionality of the pass.
set csets {}
state transaction {
- CreateRevisionChangesets csets ; # Group file revisions into csets.
- CreateSymbolChangesets csets ; # Create csets for tags and branches.
- PersistTheChangesets $csets
+ CreateRevisionChangesets csets ; # Group file revisions into csets.
+ BreakInternalDependencies csets ; # Split the csets based on internal conflicts.
+ CreateSymbolChangesets csets ; # Create csets for tags and branches.
+ PersistTheChangesets $csets
}
return
}
@@ -270,16 +272,62 @@
log write 4 initcsets "Created [nsp $n {symbol changeset}]"
return
}
+ proc BreakInternalDependencies {cv} {
+ upvar 1 $cv csets
+
+ # This code operates on the revision changesets created by
+ # 'CreateRevisionChangesets'. As such it has to follow after
+ # it, before the symbol changesets are made. The changesets
+ # are inspected for internal conflicts and any such are broken
+ # by splitting the problematic changeset into multiple
+ # fragments. The results are changesets which have no internal
+ # dependencies, only external ones.
+
+ log write 3 initcsets {Break internal dependencies}
+ set n 0
+
+ foreach cset $csets {
+ # The main method for splitting does only one split, which
+ # may not be enough. The code here iterates until no more
+ # splits can be performed. An iterative algorithm was
+ # chosen over a recursive one to prevent running into
+ # stack limits.
+
+ set tosplit [list $cset]
+ set at 0
+ while {$at < [llength $tosplit]} {
+ # Note here how we are __not__ advancing in the list
+ # when we were able to break the current
+ # changeset into two pieces, causing the loop to
+ # immediately check the first of the two pieces
+ # again for further break possibilities. The
+ # other piece is added at the end, thus processed
+ # later.
+ while {[[lindex $tosplit $at] breakinternaldependencies tosplit]} {}
+ incr at
+ }
+
+ # At last the generated fragments are added to the main
+ # list of changesets. The first element is skipped as it
+ # is already in the list.
+ foreach cset [lrange $tosplit 1 end] { lappend csets $cset ; incr n }
+ }
+
+ log write 4 initcsets "Created [nsp $n {additional revision changeset}]"
+ log write 4 initcsets Ok.
+ return
+ }
+
proc PersistTheChangesets {csets} {
- log write 3 initcsets {Saving the created changesets to the persistent state}
+ log write 3 initcsets "Saving [nsp [llength $csets] {initial changeset}] to the persistent state"
foreach cset $csets {
$cset persist
}
- log write 4 initcsets {Ok.}
+ log write 4 initcsets Ok.
return
}
# # ## ### ##### ######## #############