Diff
Not logged in

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