# HG changeset patch # User Bryan O'Sullivan # Date 2008-01-25 23:56:22 # Node ID 5963c0ad2853732b27b3fd07f88264309b2bd348 # Parent ffaf2419de448b9332420c40a85d2381e70af3fb # Parent b75105de8573831f4bfef10556e90e7f883ae8d5 Merge with crew diff --git a/hgext/graphlog.py b/hgext/graphlog.py --- a/hgext/graphlog.py +++ b/hgext/graphlog.py @@ -5,11 +5,12 @@ # This software may be used and distributed according to the terms of # the GNU General Public License, incorporated herein by reference. +import os import sys from mercurial.cmdutil import revrange, show_changeset from mercurial.i18n import _ from mercurial.node import nullid, nullrev -from mercurial.util import Abort +from mercurial.util import Abort, canonpath def revision_grapher(repo, start_rev, stop_rev): """incremental revision grapher @@ -63,6 +64,62 @@ def revision_grapher(repo, start_rev, st revs = next_revs curr_rev -= 1 +def filelog_grapher(repo, path, start_rev, stop_rev): + """incremental file log grapher + + This generator function walks through the revision history of a + single file from revision start_rev to revision stop_rev (which must + be less than or equal to start_rev) and for each revision emits + tuples with the following elements: + + - Current revision. + - Current node. + - Column of the current node in the set of ongoing edges. + - Edges; a list of (col, next_col) indicating the edges between + the current node and its parents. + - Number of columns (ongoing edges) in the current revision. + - The difference between the number of columns (ongoing edges) + in the next revision and the number of columns (ongoing edges) + in the current revision. That is: -1 means one column removed; + 0 means no columns added or removed; 1 means one column added. + """ + + assert start_rev >= stop_rev + curr_rev = start_rev + revs = [] + filerev = repo.file(path).count() - 1 + while filerev >= 0: + fctx = repo.filectx(path, fileid=filerev) + + # Compute revs and next_revs. + if filerev not in revs: + revs.append(filerev) + rev_index = revs.index(filerev) + next_revs = revs[:] + + # Add parents to next_revs. + parents = [f.filerev() for f in fctx.parents()] + parents_to_add = [] + for parent in parents: + if parent not in next_revs: + parents_to_add.append(parent) + parents_to_add.sort() + next_revs[rev_index:rev_index + 1] = parents_to_add + + edges = [] + for parent in parents: + edges.append((rev_index, next_revs.index(parent))) + + changerev = fctx.linkrev() + if changerev <= start_rev: + node = repo.changelog.node(changerev) + n_columns_diff = len(next_revs) - len(revs) + yield (changerev, node, rev_index, edges, len(revs), n_columns_diff) + if changerev <= stop_rev: + break + revs = next_revs + filerev -= 1 + def get_rev_parents(repo, rev): return [x for x in repo.changelog.parentrevs(rev) if x != nullrev] @@ -141,7 +198,7 @@ def get_revs(repo, rev_opt): else: return (repo.changelog.count() - 1, 0) -def graphlog(ui, repo, **opts): +def graphlog(ui, repo, path=None, **opts): """show revision history alongside an ASCII revision graph Print a revision history alongside a revision graph drawn with @@ -157,7 +214,11 @@ def graphlog(ui, repo, **opts): if start_rev == nullrev: return cs_printer = show_changeset(ui, repo, opts) - grapher = revision_grapher(repo, start_rev, stop_rev) + if path: + cpath = canonpath(repo.root, os.getcwd(), path) + grapher = filelog_grapher(repo, cpath, start_rev, stop_rev) + else: + grapher = revision_grapher(repo, start_rev, stop_rev) repo_parents = repo.dirstate.parents() prev_n_columns_diff = 0 prev_node_index = 0 @@ -261,5 +322,5 @@ cmdtable = { ('r', 'rev', [], _('show the specified revision or range')), ('', 'style', '', _('display using template map file')), ('', 'template', '', _('display with template'))], - _('hg glog [OPTION]...')), + _('hg glog [OPTION]... [FILE]')), } diff --git a/tests/test-glog b/tests/test-glog --- a/tests/test-glog +++ b/tests/test-glog @@ -139,5 +139,8 @@ hg glog -q echo % glog hg glog +echo % file glog +hg glog 5 + echo % unused arguments -hg glog -q foo || echo failed +hg glog -q foo bar || echo failed diff --git a/tests/test-glog.out b/tests/test-glog.out --- a/tests/test-glog.out +++ b/tests/test-glog.out @@ -307,9 +307,17 @@ o changeset: 0:7aa22e58e8c1 date: Thu Jan 01 00:00:00 1970 +0000 summary: (0) root +% file glog +o changeset: 5:3589c3c477ab + parent: 3:02173ffbf857 + parent: 4:e2cad8233c77 + user: test + date: Thu Jan 01 00:00:05 1970 +0000 + summary: (5) expand + % unused arguments hg glog: invalid arguments -hg glog [OPTION]... +hg glog [OPTION]... [FILE] show revision history alongside an ASCII revision graph failed