summaryrefslogtreecommitdiff
path: root/tools/cvs2fossil/filerevtree
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cvs2fossil/filerevtree')
-rw-r--r--tools/cvs2fossil/filerevtree178
1 files changed, 178 insertions, 0 deletions
diff --git a/tools/cvs2fossil/filerevtree b/tools/cvs2fossil/filerevtree
new file mode 100644
index 0000000..7df6ae4
--- /dev/null
+++ b/tools/cvs2fossil/filerevtree
@@ -0,0 +1,178 @@
+#!/bin/sh
+## -*- tcl -*- \
+exec tclsh "$0" ${1+"$@"}
+
+# # ## ### ##### ######## ############# #####################
+## Copyright (c) 2007 Andreas Kupries.
+#
+# This software is licensed as described in the file LICENSE, which
+# you should have received as part of this distribution.
+#
+# This software consists of voluntary contributions made by many
+# individuals. For exact contribution history, see the revision
+# history and logs, available at http://fossil-scm.hwaci.com/fossil
+# # ## ### ##### ######## ############# #####################
+
+## Helper application, debugging of cvs2fossil. This application
+## extracts the tree of revisions for a file of interest, specified
+## either directly through its id, or indirectly through the id of a
+## revision it contains, and generates a nice graphical representation
+## of it (png image). It uses GraphiViz's 'dot' tool to do all the
+## layouting.
+
+# # ## ### ##### ######## ############# #####################
+## Requirements, extended package management for local packages.
+
+lappend auto_path [file join [file dirname [info script]] lib]
+
+package require Tcl 8.4 ; # Required runtime.
+package require struct::graph ; # Graph handling.
+package require struct::list ; # Higher order list ops.
+package require vc::fossil::import::cvs::project::rev ; # Changesets
+package require vc::fossil::import::cvs::state ; # State storage.
+package require vc::tools::misc ; # Min/max.
+package require vc::tools::dot ; # Graph export to DOT.
+package require vc::tools::trouble ; # Error reporting
+package require vc::tools::log ; # User feedback
+
+namespace import ::vc::fossil::import::cvs::state
+namespace import ::vc::fossil::import::cvs::project::rev
+namespace import ::vc::tools::dot
+namespace import ::vc::tools::trouble
+namespace import ::vc::tools::log
+namespace import ::vc::tools::misc::*
+
+log verbosity 0
+
+# Process the command line, i.e. get the database to access, and file
+# of interest. The latter can be specified by name, id, or indirectly
+# through the id of one of the revisions it contains.
+
+state use [lindex $argv 0]
+state reading project
+state reading file
+state reading revision
+state reading revisionbranchchildren
+state reading changeset
+state reading csitem
+state reading csorder
+
+set what [lindex $argv 1]
+set centralrid -1
+
+switch -exact -- $what {
+ rid {
+ # Get the revision of interest, identified by the internal
+ # numeric id used by cvs2fossil.
+ set centralrid [lindex $argv 2]
+
+ puts "Revision : [state one { SELECT rev FROM revision WHERE rid = $centralrid }] ($centralrid)"
+
+ # Map it to the file containing the revision of interest.
+ set fid [state one { SELECT fid FROM revision WHERE rid = $centralrid }]
+ }
+ fid {
+ # Get the file of interest, identified by internal numeric id
+ # used by cvs2fossil.
+ set fid [lindex $argv 2]
+ }
+ fname {
+ # Get the file of interest, identified by its name.
+
+ set fname [lindex $argv 2]
+ set fid [state one { SELECT fid FROM file WHERE name == $fname }]
+ }
+ default {
+ trouble fatal \
+ "Unknown spec \"$what\", expected one of \"fid\", \"fname\", or \"rid\""
+ }
+}
+trouble abort?
+
+set pid [state one { SELECT pid FROM file WHERE fid == $fid }]
+
+puts "File : [state one { SELECT name FROM file WHERE fid = $fid }] ($fid)"
+puts "Project : [state one { SELECT name FROM project WHERE pid = $pid }] ($pid)"
+
+# Get the data of all revisions in the file of interest, as a list for
+# iteration, and as array for random access of neighbouring revisions.
+
+array set rev {}
+foreach {rid revnr lod date isdefault} [set revisions [state run {
+ SELECT R.rid, R.rev, S.name, R.date, R.isdefault
+ FROM revision R, symbol S
+ WHERE R.fid = $fid
+ AND R.lod = S.sid
+}]] {
+ set cs [state run {
+ SELECT CR.cid, CO.pos, CT.name
+ FROM csitem CR, csorder CO, cstype CT, changeset C
+ WHERE CR.iid = $rid
+ AND CR.cid = CO.cid
+ AND CR.cid = C.cid
+ AND CT.tid = C.type
+ }]
+
+ set rev($rid) [list $revnr $lod $date $isdefault $cs]
+}
+
+puts "#Revs : [array size rev]"
+
+# Start the graph
+
+struct::graph dg
+
+# Convert the revisions into nodes of the graph, and use node
+# attributes to highlight various pieces of interest for the dot
+# conversion. Label => Revnr, Symbol (LOD), Changeset id (if
+# available), formatted date. Background fill colors to show the
+# different branches ?.
+
+foreach {rid revnr lod date isdefault} $revisions {
+ set label "$rid = <$revnr> @ $lod / [clock format $date]"
+ set cs [lindex $rev($rid) 4]
+ if {[llength $cs]} {
+ foreach {cs ord cstype} $cs {
+ append label "\\nCS/${cstype}($cs) @$ord"
+ }
+ }
+ set key [list rev $rid]
+ dg node insert $key
+ dg node set $key label $label
+ dg node set $key shape [expr {$isdefault ? "diamond" : "box"}]
+}
+
+# Go through the revisions a second time and set up the arcs based on
+# the stored successor information.
+
+::vc::fossil::import::cvs::project::rev::rev successors dep [array names rev]
+
+proc Ord {cmd rid} {return 0
+ global rev
+ set ords {}
+ foreach {cs ord cstype} [lindex $rev($rid) 4] { lappend ords $ord }
+ return [$cmd $ords]
+}
+
+foreach {rid children} [array get dep] {
+ set max [Ord max $rid]
+
+ foreach child $children {
+ if {[catch {
+ set a [dg arc insert $rid $child]
+ }]} continue
+
+ if {$max > [Ord min $child]} {
+ puts "Backward : $rid -> $child"
+ dg arc set $a color red
+ }
+ }
+}
+
+# Convert the graph to dot, then run the layouter and convert to png,
+# at last show the image.
+
+vc::tools::dot layout png dg SymbolTree st.png
+exec display st.png
+file delete st.png
+exit