Check-in [510cd02303]
Not logged in
Overview

SHA1 Hash:510cd0230374a2ccb952d45203fde9245ddbf8e6
Date: 2007-10-19 07:23:57
User: aku
Comment:Continued the work on pass II, wrangling a file into shape. Completed handling of unnecessary initial deletions on branches.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified tools/cvs2fossil/lib/c2f_file.tcl from [a38feddbdf] to [26e48dda4d].

@@ -691,14 +691,13 @@
 	}
 	return
     }
 
     method RemoveIrrelevantDeletions {} {
-	# From cvs2fossil:
-	# If a file is added on a branch, then a trunk revision is
-	# added at the same time in the 'Dead' state.  This revision
-	# doesn't do anything useful, so delete it.
+	# From cvs2svn: If a file is added on a branch, then a trunk
+	# revision is added at the same time in the 'Dead' state.
+	# This revision doesn't do anything useful, so delete it.
 
 	foreach root $myroots {
 	    if {[$root isneeded]} continue
 	    log write 2 file "Removing unnecessary dead revision [$root revnr]"
 
@@ -731,17 +730,80 @@
 	    # any tags that were set on it.
 
 	    $root removealltags
 
 	    # This can only happen once per file, and we might have
-	    # just changed myroots, so break out of the loop:
+	    # just changed myroots, so end the loop
 	    break
 	}
 	return
     }
 
     method RemoveInitialBranchDeletions {} {
+	# From cvs2svn: If the first revision on a branch is an
+	# unnecessary delete, remove it.
+	#
+	# If a file is added on a branch (whether or not it already
+	# existed on trunk), then new versions of CVS add a first
+	# branch revision in the 'dead' state (to indicate that the
+	# file did not exist on the branch when the branch was
+	# created) followed by the second branch revision, which is an
+	# add.  When we encounter this situation, we sever the branch
+	# from trunk and delete the first branch revision.
+
+	# At this point we may have already multiple roots in myroots,
+	# we have to process them all.
+
+	set lodroots [$self LinesOfDevelopment]
+	foreach root $lodroots {
+	    if {[$root isneededbranchdel]} continue
+	    log write 2 file "Removing unnecessary initial branch delete [$root revnr]"
+
+	    set branch [$root parentbranch]
+	    set parent [$root parent]
+	    set child  [$root child]
+
+	    ldelete myroots $root
+	    unset myrev([$root revnr])
+	    $child cutfromparent
+	    lappend myroots $child
+
+	    $parent removechildonbranch $root
+	    $parent removebranch        $branch
+
+	    $branch destroy
+	    $root   destroy
+	}
+	return
+    }
+
+    method LinesOfDevelopment {} {
+	# Determine all lines of development for the file. This are
+	# the known roots, and the root of all branches found on the
+	# line of primary children.
+
+	set lodroots {}
+	foreach root $myroots {
+	    $self AddBranchedLinesOfDevelopment lodroots $root
+	    lappend lodroots $root
+	}
+	return $lodroots
+    }
+
+    method AddBranchedLinesOfDevelopment {lv root} {
+	upvar 1 $lv lodroots
+	while {$root ne ""} {
+	    foreach branch [$root branches] {
+		if {![$branch haschild]} continue
+		set child [$branch child]
+		# Recurse into the branch for deeper branches.
+		$self AddBranchedLinesOfDevelopment lodroots $child
+		lappend lodroots $child
+	    }
+	    set root [$root child]
+	}
+	return
     }
 
     method ExcludeNonTrunkInformation {} {
     }
 

Modified tools/cvs2fossil/lib/c2f_frev.tcl from [49171e7a40] to [f4f21fda7f].

@@ -66,10 +66,47 @@
 
 	set gen "file [file tail [$myfile usrpath]] was initially added on branch [$firstbranch name]."
 	set log [$myfile commitmessageof $mymetaid]
 
 	return [expr {$log ne $gen}]
+    }
+
+    method isneededbranchdel {} {
+	if {$myparentbranch eq ""}           {return 1} ; # not first on a branch, needed
+	set base [$myparentbranch parent]
+	if {$base           eq ""}           {return 1} ; # branch has parent lod, needed
+	if {[$self LODLength] < 2}           {return 1} ; # our lod contains only ourselves, needed.
+	if {$myoperation ne "delete"}        {return 1} ; # Not a deletion, needed
+	if {[llength $mytags]}               {return 1} ; # Have tags, needed
+	if {[llength $mybranches]}           {return 1} ; # Have other branches, needed
+	if {abs($mydate - [$base date]) > 2} {return 1} ; # Next rev > 2 seconds apart, needed
+
+        # FIXME: This message will not match if the RCS file was
+        # renamed manually after it was created.
+
+	set qfile [string map {
+	    .  \\.  ?  \\?  *  \\*  \\ \\\\ +  \\+  ^ \\^ $ \\$
+	    \[ \\\[ \] \\\] (  \\(   ) \\)  \{ \\\{ \} \\\}
+	} [file tail [$myfile usrpath]]]
+	set pattern "file $qfile was added on branch .* on \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}( \[+-\]\\d{4})?"
+	set log     [$myfile commitmessageof $mymetaid]
+
+	# Not the special message, needed
+	if {![regexp -- $pattern $log]} {return 1}
+
+	# This is an unneeded initial branch delete.
+	return 0
+    }
+
+    method LODLength {} {
+	set n 1 ; # count self
+	set rev $mychild
+	while {$rev ne ""} {
+	    incr n
+	    set rev [$rev child]
+	}
+	return $n
     }
 
     # Basic parent/child linkage __________
 
     method hasparent {} { return [expr {$myparent ne ""}] }

Modified tools/cvs2fossil/lib/c2f_repository.tcl from [3ba48f18aa] to [ac4b426bcc].

@@ -76,39 +76,39 @@
     }
 
     typemethod defauthor {a} {
 	if {![info exists myauthor($a)]} {
 	    set myauthor($a) [incr myauthorcnt]
-	    log write 6 repository "author '$a' =  $myauthor($a)"
+	    log write 7 repository "author '$a' =  $myauthor($a)"
 	}
 	return $myauthor($a)
     }
 
     typemethod defcmessage {cm} {
 	if {![info exists mycmsg($cm)]} {
 	    set mycmsg($cm) [set cid [incr mycmsgcnt]]
 	    set mycmsginv($cid) $cm
-	    log write 6 repository "cmessage '$cm' =  $cid"
+	    log write 7 repository "cmessage '$cm' =  $cid"
 	}
 	return $mycmsg($cm)
     }
 
     typemethod defsymbol {pid name} {
 	set key [list $pid $name]
 	if {![info exists mysymbol($key)]} {
 	    set mysymbol($key) [incr mysymbolcnt]
-	    log write 6 repository "symbol ($key) =  $mysymbol($key)"
+	    log write 7 repository "symbol ($key) =  $mysymbol($key)"
 	}
 	return $mysymbol($key)
     }
 
     typemethod defmeta {pid bid aid cid} {
 	set key [list $pid $bid $aid $cid]
 	if {![info exists mymeta($key)]} {
 	    set mymeta($key) [set mid [incr mymetacnt]]
 	    set mymetainv($mid) $key
-	    log write 6 repository "meta ($key) =  $mymeta($key)"
+	    log write 7 repository "meta ($key) =  $mymeta($key)"
 	}
 	return $mymeta($key)
     }
 
     typemethod commitmessageof {metaid} {