# HG changeset patch # User Patrick Mezard # Date 2009-12-13 17:06:24 # Node ID f780b1098efc0bdecae92966ab56eb8808e1d402 # Parent 9dd4e2859482d4915658371f3dc94aa7adfb084d templatekw: change {file_copies} behaviour, add {file_copies_switch} {file_copies} template now displays file copies with or without the --copies switch being set. A new {file_copies_switch} template implements the former behaviour. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -651,7 +651,7 @@ class changeset_printer(object): return 1 return 0 - def show(self, ctx, copies=(), **props): + def show(self, ctx, copies=None, **props): if self.buffered: self.ui.pushbuffer() self._show(ctx, copies, props) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -10,7 +10,7 @@ from lock import release from i18n import _, gettext import os, re, sys, difflib, time, tempfile import hg, util, revlog, bundlerepo, extensions, copies, error -import patch, help, mdiff, url, encoding +import patch, help, mdiff, url, encoding, templatekw import archival, changegroup, cmdutil, sshserver, hbisect from hgweb import server import merge as merge_ @@ -2018,34 +2018,9 @@ def log(ui, repo, *pats, **opts): limit = cmdutil.loglimit(opts) count = 0 + endrev = None if opts.get('copies') and opts.get('rev'): endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1 - else: - endrev = len(repo) - rcache = {} - def getrenamed(fn, rev): - '''looks up all renames for a file (up to endrev) the first - time the file is given. It indexes on the changerev and only - parses the manifest if linkrev != changerev. - Returns rename info for fn at changerev rev.''' - if fn not in rcache: - rcache[fn] = {} - fl = repo.file(fn) - for i in fl: - lr = fl.linkrev(i) - renamed = fl.renamed(fl.node(i)) - rcache[fn][lr] = renamed - if lr >= endrev: - break - if rev in rcache[fn]: - return rcache[fn][rev] - - # If linkrev != rev (i.e. rev not found in rcache) fallback to - # filectx logic. - try: - return repo[rev][fn].renamed() - except error.LookupError: - return None df = False if opts["date"]: @@ -2075,8 +2050,10 @@ def log(ui, repo, *pats, **opts): else: return - copies = [] + copies = None if opts.get('copies') and rev: + copies = [] + getrenamed = templatekw.getrenamedfn(repo, endrev=endrev) for fn in ctx.files(): rename = getrenamed(fn, rev) if rename: diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py --- a/mercurial/templatekw.py +++ b/mercurial/templatekw.py @@ -6,7 +6,7 @@ # GNU General Public License version 2, incorporated herein by reference. from node import hex -import encoding, patch, util +import encoding, patch, util, error def showlist(templ, name, values, plural=None, **args): '''expand set of values. @@ -108,6 +108,38 @@ def getlatesttags(repo, ctx, cache): latesttags[rev] = pdate, pdist + 1, ptag return latesttags[rev] +def getrenamedfn(repo, endrev=None): + rcache = {} + if endrev is None: + endrev = len(repo) + + def getrenamed(fn, rev): + '''looks up all renames for a file (up to endrev) the first + time the file is given. It indexes on the changerev and only + parses the manifest if linkrev != changerev. + Returns rename info for fn at changerev rev.''' + if fn not in rcache: + rcache[fn] = {} + fl = repo.file(fn) + for i in fl: + lr = fl.linkrev(i) + renamed = fl.renamed(fl.node(i)) + rcache[fn][lr] = renamed + if lr >= endrev: + break + if rev in rcache[fn]: + return rcache[fn][rev] + + # If linkrev != rev (i.e. rev not found in rcache) fallback to + # filectx logic. + try: + return repo[rev][fn].renamed() + except error.LookupError: + return None + + return getrenamed + + def showauthor(repo, ctx, templ, **args): return ctx.user() @@ -141,8 +173,27 @@ def showextras(repo, ctx, templ, **args) def showfileadds(repo, ctx, templ, revcache, **args): return showlist(templ, 'file_add', getfiles(repo, ctx, revcache)[1], **args) -def showfilecopies(repo, ctx, templ, revcache, **args): - c = [{'name': x[0], 'source': x[1]} for x in revcache['copies']] +def showfilecopies(repo, ctx, templ, cache, revcache, **args): + copies = revcache.get('copies') + if copies is None: + if 'getrenamed' not in cache: + cache['getrenamed'] = getrenamedfn(repo) + copies = [] + getrenamed = cache['getrenamed'] + for fn in ctx.files(): + rename = getrenamed(fn, ctx.rev()) + if rename: + copies.append((fn, rename[0])) + + c = [{'name': x[0], 'source': x[1]} for x in copies] + return showlist(templ, 'file_copy', c, plural='file_copies', **args) + +# showfilecopiesswitch() displays file copies only if copy records are +# provided before calling the templater, usually with a --copies +# command line switch. +def showfilecopiesswitch(repo, ctx, templ, cache, revcache, **args): + copies = revcache.get('copies') or [] + c = [{'name': x[0], 'source': x[1]} for x in copies] return showlist(templ, 'file_copy', c, plural='file_copies', **args) def showfiledels(repo, ctx, templ, revcache, **args): @@ -184,6 +235,7 @@ keywords = { 'extras': showextras, 'file_adds': showfileadds, 'file_copies': showfilecopies, + 'file_copies_switch': showfilecopiesswitch, 'file_dels': showfiledels, 'file_mods': showfilemods, 'files': showfiles, diff --git a/mercurial/templates/map-cmdline.default b/mercurial/templates/map-cmdline.default --- a/mercurial/templates/map-cmdline.default +++ b/mercurial/templates/map-cmdline.default @@ -1,7 +1,7 @@ changeset = 'changeset: {rev}:{node|short}\n{branches}{tags}{parents}user: {author}\ndate: {date|date}\nsummary: {desc|firstline}\n\n' changeset_quiet = '{rev}:{node|short}\n' -changeset_verbose = 'changeset: {rev}:{node|short}\n{branches}{tags}{parents}user: {author}\ndate: {date|date}\n{files}{file_copies}description:\n{desc|strip}\n\n\n' -changeset_debug = 'changeset: {rev}:{node}\n{branches}{tags}{parents}{manifest}user: {author}\ndate: {date|date}\n{file_mods}{file_adds}{file_dels}{file_copies}{extras}description:\n{desc|strip}\n\n\n' +changeset_verbose = 'changeset: {rev}:{node|short}\n{branches}{tags}{parents}user: {author}\ndate: {date|date}\n{files}{file_copies_switch}description:\n{desc|strip}\n\n\n' +changeset_debug = 'changeset: {rev}:{node}\n{branches}{tags}{parents}{manifest}user: {author}\ndate: {date|date}\n{file_mods}{file_adds}{file_dels}{file_copies_switch}{extras}description:\n{desc|strip}\n\n\n' start_files = 'files: ' file = ' {file}' end_files = '\n' @@ -14,9 +14,9 @@ end_file_adds = '\n' start_file_dels = 'files-: ' file_del = ' {file_del}' end_file_dels = '\n' -start_file_copies = 'copies: ' +start_file_copies_switch = 'copies: ' file_copy = ' {name} ({source})' -end_file_copies = '\n' +end_file_copies_switch = '\n' parent = 'parent: {rev}:{node|formatnode}\n' manifest = 'manifest: {rev}:{node}\n' branch = 'branch: {branch}\n' diff --git a/tests/test-command-template b/tests/test-command-template --- a/tests/test-command-template +++ b/tests/test-command-template @@ -94,8 +94,8 @@ cat changelog echo "# keys work" for key in author branches date desc file_adds file_dels file_mods \ - 'file_copies%filecopy' files manifest node parents rev tags diffstat \ - extras; do + 'file_copies%filecopy' 'file_copies_switch%filecopy' files \ + manifest node parents rev tags diffstat extras; do for mode in '' --verbose --debug; do hg log $mode --template "$key$mode: {$key}\n" done diff --git a/tests/test-command-template.out b/tests/test-command-template.out --- a/tests/test-command-template.out +++ b/tests/test-command-template.out @@ -380,7 +380,7 @@ file_mods--debug: c file_mods--debug: file_mods--debug: file_mods--debug: -file_copies%filecopy: +file_copies%filecopy: fourth (second) file_copies%filecopy: file_copies%filecopy: file_copies%filecopy: @@ -389,7 +389,7 @@ file_copies%filecopy: file_copies%filecopy: file_copies%filecopy: file_copies%filecopy: -file_copies%filecopy--verbose: +file_copies%filecopy--verbose: fourth (second) file_copies%filecopy--verbose: file_copies%filecopy--verbose: file_copies%filecopy--verbose: @@ -398,6 +398,7 @@ file_copies%filecopy--verbose: file_copies%filecopy--verbose: file_copies%filecopy--verbose: file_copies%filecopy--verbose: +file_copies%filecopy--debug: fourth (second) file_copies%filecopy--debug: file_copies%filecopy--debug: file_copies%filecopy--debug: @@ -406,7 +407,33 @@ file_copies%filecopy--debug: file_copies%filecopy--debug: file_copies%filecopy--debug: file_copies%filecopy--debug: -file_copies%filecopy--debug: +file_copies_switch%filecopy: +file_copies_switch%filecopy: +file_copies_switch%filecopy: +file_copies_switch%filecopy: +file_copies_switch%filecopy: +file_copies_switch%filecopy: +file_copies_switch%filecopy: +file_copies_switch%filecopy: +file_copies_switch%filecopy: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--verbose: +file_copies_switch%filecopy--debug: +file_copies_switch%filecopy--debug: +file_copies_switch%filecopy--debug: +file_copies_switch%filecopy--debug: +file_copies_switch%filecopy--debug: +file_copies_switch%filecopy--debug: +file_copies_switch%filecopy--debug: +file_copies_switch%filecopy--debug: +file_copies_switch%filecopy--debug: files: fourth second third files: second files: diff --git a/tests/test-git-import b/tests/test-git-import --- a/tests/test-git-import +++ b/tests/test-git-import @@ -141,7 +141,7 @@ diff --git a/rename2 b/rename3-2 rename from rename2 rename to rename3-2 EOF -hg log -vCr. --template '{rev} {files} / {file_copies%filecopy}\n' +hg log -vr. --template '{rev} {files} / {file_copies%filecopy}\n' hg locate rename2 rename3 rename3-2 hg cat rename3 diff --git a/tests/test-log b/tests/test-log --- a/tests/test-log +++ b/tests/test-log @@ -31,20 +31,24 @@ hg log -vf a echo % many renames hg log -vf e -echo % log copies +echo '% log copies with --copies' hg log -vC --template '{rev} {file_copies%filecopy}\n' +echo '% log copies switch without --copies' +hg log -v --template '{rev} {file_copies_switch%filecopy}\n' +echo '% log copies switch with --copies' +hg log -vC --template '{rev} {file_copies_switch%filecopy}\n' echo % log copies, non-linear manifest hg up -C 3 hg mv dir/b e echo foo > foo hg ci -Ame2 -d '6 0' -hg log -vC --template '{rev} {file_copies%filecopy}\n' -r 5 +hg log -v --template '{rev} {file_copies%filecopy}\n' -r 5 echo % log copies, execute bit set chmod +x e hg ci -me3 -d '7 0' -hg log -vC --template '{rev} {file_copies%filecopy}\n' -r 6 +hg log -v --template '{rev} {file_copies%filecopy}\n' -r 6 echo '% log -p d' hg log -pv d diff --git a/tests/test-log.out b/tests/test-log.out --- a/tests/test-log.out +++ b/tests/test-log.out @@ -76,7 +76,19 @@ description: a -% log copies +% log copies with --copies +4 e (dir/b) +3 b (a) +2 dir/b (b) +1 b (a) +0 +% log copies switch without --copies +4 +3 +2 +1 +0 +% log copies switch with --copies 4 e (dir/b) 3 b (a) 2 dir/b (b) diff --git a/tests/test-mq b/tests/test-mq --- a/tests/test-mq +++ b/tests/test-mq @@ -387,10 +387,10 @@ hg ci -m 'change foo' hg up -C 1 hg qrefresh --git 2>&1 | grep -v 'saving bundle' cat .hg/patches/bar -hg log -vC --template '{rev} {file_copies%filecopy}\n' -r . +hg log -v --template '{rev} {file_copies%filecopy}\n' -r . hg qrefresh --git cat .hg/patches/bar -hg log -vC --template '{rev} {file_copies%filecopy}\n' -r . +hg log -v --template '{rev} {file_copies%filecopy}\n' -r . hg qrefresh grep 'diff --git' .hg/patches/bar @@ -403,12 +403,12 @@ hg mv bar quux hg mv baz bleh hg qrefresh --git 2>&1 | grep -v 'saving bundle' cat .hg/patches/bar -hg log -vC --template '{rev} {file_copies%filecopy}\n' -r . +hg log -v --template '{rev} {file_copies%filecopy}\n' -r . hg mv quux fred hg mv bleh barney hg qrefresh --git cat .hg/patches/bar -hg log -vC --template '{rev} {file_copies%filecopy}\n' -r . +hg log -v --template '{rev} {file_copies%filecopy}\n' -r . echo % refresh omitting an added file hg qnew baz