mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
db45da1208
When trying to read log output from many projects at once it can be difficult to make sense of which messages came from where. For many professional developers it is common to want to view the last week's worth of your work, so you can write a weekly summary of your activity for your status report. This is easier with the new -p option: repo forall -pc git log --reverse --since=1.week.ago --author=sop produces a report of all commits written by me in the last week, formatted in a paged output display, with headers inserted in front of each project's output. Where this can be even more useful is with git log's pickaxe, e.g. now we can use: repo forall -pc git log -Sbar v1.0..v1.1 to locate all additions or removals of the symbol 'bar' since v1.0, up to and including v1.1. Before displaying the matching commits in a project, a project header is shown, giving the user some context information for the matching results. Signed-off-by: Shawn O. Pearce <sop@google.com>
161 lines
3.5 KiB
Python
161 lines
3.5 KiB
Python
#
|
|
# Copyright (C) 2008 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import os
|
|
import sys
|
|
|
|
import pager
|
|
from git_config import GitConfig
|
|
|
|
COLORS = {None :-1,
|
|
'normal' :-1,
|
|
'black' : 0,
|
|
'red' : 1,
|
|
'green' : 2,
|
|
'yellow' : 3,
|
|
'blue' : 4,
|
|
'magenta': 5,
|
|
'cyan' : 6,
|
|
'white' : 7}
|
|
|
|
ATTRS = {None :-1,
|
|
'bold' : 1,
|
|
'dim' : 2,
|
|
'ul' : 4,
|
|
'blink' : 5,
|
|
'reverse': 7}
|
|
|
|
RESET = "\033[m"
|
|
|
|
def is_color(s): return s in COLORS
|
|
def is_attr(s): return s in ATTRS
|
|
|
|
def _Color(fg = None, bg = None, attr = None):
|
|
fg = COLORS[fg]
|
|
bg = COLORS[bg]
|
|
attr = ATTRS[attr]
|
|
|
|
if attr >= 0 or fg >= 0 or bg >= 0:
|
|
need_sep = False
|
|
code = "\033["
|
|
|
|
if attr >= 0:
|
|
code += chr(ord('0') + attr)
|
|
need_sep = True
|
|
|
|
if fg >= 0:
|
|
if need_sep:
|
|
code += ';'
|
|
need_sep = True
|
|
|
|
if fg < 8:
|
|
code += '3%c' % (ord('0') + fg)
|
|
else:
|
|
code += '38;5;%d' % fg
|
|
|
|
if bg >= 0:
|
|
if need_sep:
|
|
code += ';'
|
|
need_sep = True
|
|
|
|
if bg < 8:
|
|
code += '4%c' % (ord('0') + bg)
|
|
else:
|
|
code += '48;5;%d' % bg
|
|
code += 'm'
|
|
else:
|
|
code = ''
|
|
return code
|
|
|
|
|
|
class Coloring(object):
|
|
def __init__(self, config, type):
|
|
self._section = 'color.%s' % type
|
|
self._config = config
|
|
self._out = sys.stdout
|
|
|
|
on = self._config.GetString(self._section)
|
|
if on is None:
|
|
on = self._config.GetString('color.ui')
|
|
|
|
if on == 'auto':
|
|
if pager.active or os.isatty(1):
|
|
self._on = True
|
|
else:
|
|
self._on = False
|
|
elif on in ('true', 'always'):
|
|
self._on = True
|
|
else:
|
|
self._on = False
|
|
|
|
def redirect(self, out):
|
|
self._out = out
|
|
|
|
@property
|
|
def is_on(self):
|
|
return self._on
|
|
|
|
def write(self, fmt, *args):
|
|
self._out.write(fmt % args)
|
|
|
|
def flush(self):
|
|
self._out.flush()
|
|
|
|
def nl(self):
|
|
self._out.write('\n')
|
|
|
|
def printer(self, opt=None, fg=None, bg=None, attr=None):
|
|
s = self
|
|
c = self.colorer(opt, fg, bg, attr)
|
|
def f(fmt, *args):
|
|
s._out.write(c(fmt, *args))
|
|
return f
|
|
|
|
def colorer(self, opt=None, fg=None, bg=None, attr=None):
|
|
if self._on:
|
|
c = self._parse(opt, fg, bg, attr)
|
|
def f(fmt, *args):
|
|
str = fmt % args
|
|
return ''.join([c, str, RESET])
|
|
return f
|
|
else:
|
|
def f(fmt, *args):
|
|
return fmt % args
|
|
return f
|
|
|
|
def _parse(self, opt, fg, bg, attr):
|
|
if not opt:
|
|
return _Color(fg, bg, attr)
|
|
|
|
v = self._config.GetString('%s.%s' % (self._section, opt))
|
|
if v is None:
|
|
return _Color(fg, bg, attr)
|
|
|
|
v = v.strip().lower()
|
|
if v == "reset":
|
|
return RESET
|
|
elif v == '':
|
|
return _Color(fg, bg, attr)
|
|
|
|
have_fg = False
|
|
for a in v.split(' '):
|
|
if is_color(a):
|
|
if have_fg: bg = a
|
|
else: fg = a
|
|
elif is_attr(a):
|
|
attr = a
|
|
|
|
return _Color(fg, bg, attr)
|