mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
7ebb123c54
Summary: Catnotate is a version of hg cat with output annotated with file name and line number. Such output is very useful when running hg cat on multiple files (for example in commit hooks). Test Plan: unit tests Reviewers: #sourcecontrol, pyd, mpm, durham, rmcelroy Reviewed By: rmcelroy Differential Revision: https://phabricator.fb.com/D2497470 Signature: t1:2497470:1444842798:9192ef3ef1603d068e7f38777def81a43bed0414
59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
from mercurial import extensions, util, cmdutil, commands, error, scmutil, util
|
|
from mercurial.i18n import _
|
|
import mercurial.match as matchmod
|
|
import os
|
|
|
|
cmdtable = {}
|
|
command = cmdutil.command(cmdtable)
|
|
testedwith = 'internal'
|
|
|
|
@command('^catnotate', [
|
|
('r', 'rev', '', _('print the given revision'), _('REV')),
|
|
('a', 'text', None, _('treat all files as text')),
|
|
], _('[OPTION]... FILE...'),
|
|
)
|
|
def catnotate(ui, repo, file1, *args, **opts):
|
|
"""output the current or given revision of files annotated with filename
|
|
and line number.
|
|
|
|
Print the specified files as they were at the given revision. If
|
|
no revision is given, the parent of the working directory is used.
|
|
|
|
Binary files are skipped unless -a/--text option is provided.
|
|
"""
|
|
ctx = scmutil.revsingle(repo, opts.get('rev'))
|
|
matcher = scmutil.match(ctx, (file1,) + args, opts)
|
|
files = args
|
|
prefix = ''
|
|
|
|
err = 1
|
|
# modified and stripped mercurial.cmdutil.cat follows
|
|
def write(path):
|
|
fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
|
|
pathname=os.path.join(prefix, path))
|
|
data = ctx[path].data()
|
|
if not opts.get('text') and util.binary(data):
|
|
fp.write("%s: binary file\n" % path)
|
|
return
|
|
|
|
for (num, line) in enumerate(data.split("\n"), start=1):
|
|
line = line + "\n"
|
|
fp.write("%s:%s: %s" % (path, num, line))
|
|
fp.close()
|
|
|
|
# Automation often uses hg cat on single files, so special case it
|
|
# for performance to avoid the cost of parsing the manifest.
|
|
if len(matcher.files()) == 1 and not matcher.anypats():
|
|
file = matcher.files()[0]
|
|
mf = repo.manifest
|
|
mfnode = ctx.manifestnode()
|
|
if mfnode and mf.find(mfnode, file)[0]:
|
|
write(file)
|
|
return 0
|
|
|
|
for abs in ctx.walk(matcher):
|
|
write(abs)
|
|
err = 0
|
|
|
|
return err
|