# # # add_file "tracvc/mtn/per-file-dag.py" # content [16bd01c8c27bad4fdcaf9abc036be2d41af9d33e] # # set "tracvc/mtn/per-file-dag.py" # attr "mtn:execute" # value "true" # ============================================================ --- tracvc/mtn/per-file-dag.py 16bd01c8c27bad4fdcaf9abc036be2d41af9d33e +++ tracvc/mtn/per-file-dag.py 16bd01c8c27bad4fdcaf9abc036be2d41af9d33e @@ -0,0 +1,111 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +""" +Trac Plugin for Monotone + +Copyright 2006, Thomas Moschny (address@hidden) + +{{{ +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at +your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA +}}} + +""" + +import util + +# Adjust this if you are going to execute this file directly!! +MTN_DATABASE = "/home/thomas/.monotone/monotone.db" + + +def file_dag(repo, rev, path): + """Returns a dag that contains all nodes of the revision graph in + which path was modified (added, patched or renamed). + """ + + assert path in repo.manifest(rev) + + work, done = set([(rev, path, rev)]), set() + nodes, edges = set([(rev, path)]), set() + + while work: + # examine path in rev, coming from child + current = work.pop() + rev, path, child = current + done.add(current) + + new_work = set() + + # we keep the node, if the path was changed in one of it's + # changesets + changed = False + + for cs in repo.changesets(rev): + if path in cs.added: + changed = True + # no oldrev, no oldpath, stop here + continue + + oldrev = cs.oldrev + oldpath = util.get_oldpath(path, cs.renamed) + + if path in cs.patched or path in cs.renamed: + # fixme: what about the oldpath != path case (i.e.one + # of the parents was renamed)? + changed = True + + new_work.add((oldrev, oldpath)) + + if changed: + nodes.add((rev, path)) + edges.add((rev, child)) + child = rev + + for w in new_work: + a = (w[0], w[1], child) + if not a in done: + work.add(a) + + return nodes, edges + + +# ---------------------------------------------------------------------- + +if __name__ == "__main__": + + from automate import * + + # we need a repo + repo = MTN(MTN_DATABASE, None, '/usr/bin/mtn', + 'dbmshelve:/tmp/TracMonotone-') + + # select path and rev to start + rev = '54ce05f74f0db329db05686829352311547eedd5' + path = '/mtn.1' + #rev = 'b9fedb4148ca6734e97263228fcda21865a1a420' + #path = '/tracvc/mtn/backend.py' + + # get the dag + nodes, edges = file_dag(repo, rev, path) + + # create a simple dot file + print 'digraph dag {' + print 'center=1;' + for n in nodes: + print '"%s" [label="%s"];' % (n[0], + n[0][:8] + ".." + r'\n' + n[1]) + for e in edges: + print '"%s" -> "%s";' % (e[0], e[1]) + print '}'