git hyper-blame: Added automatically ignoring revs from a file.
Added --ignore-file argument, so you can specify ignored commits in a
file rather than as raw command-line arguments. Also, automatically
searches for a file called .git-blame-ignore-revs, which is
automatically used as an ignore list by default.
Also, specifying an unknown revision (either on the command line or in a
file) now generates a warning, not an error.
Notes on some decisions:
- The file is called .git-blame-ignore-revs (not mentioning hyper-blame)
because we may use the same list in tools other than hyper-blame in
the future.
- We look at the *currently checked out* version of
.git-blame-ignore-revs (not the version at the specified revision) for
consistency with .git-ignore. Because we only expect revisions to be
added (not deleted), it should be fine to use an ignore list from a
newer version than the revision being blamed.
- We considered using git notes for the ignore list so that you could
add a revision to the ignore list without needing a follow-up CL.
However, there are some problems with this approach. git notes is not
automatically synced with git clone/pull. Also the Chromium infra
tools (Reitveld, CQ) are not set up to allow modification of git
notes, nor are changes to git notes subject to OWNERS checks. Using a
regular file ensures all users synced to a particular revision are
using the same ignore list.
BUG=574290
Review URL: https://codereview.chromium.org/1697423004
git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@298897 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/git_hyper_blame.py b/git_hyper_blame.py
index 5a7daa0..b9965a7 100755
--- a/git_hyper_blame.py
+++ b/git_hyper_blame.py
@@ -22,6 +22,9 @@
logging.getLogger().setLevel(logging.INFO)
+DEFAULT_IGNORE_FILE_NAME = '.git-blame-ignore-revs'
+
+
class Commit(object):
"""Info about a commit."""
def __init__(self, commithash):
@@ -323,12 +326,25 @@
return 0
+
+def parse_ignore_file(ignore_file):
+ for line in ignore_file:
+ line = line.split('#', 1)[0].strip()
+ if line:
+ yield line
+
+
def main(args, stdout=sys.stdout, stderr=sys.stderr):
parser = argparse.ArgumentParser(
prog='git hyper-blame',
description='git blame with support for ignoring certain commits.')
parser.add_argument('-i', metavar='REVISION', action='append', dest='ignored',
default=[], help='a revision to ignore')
+ parser.add_argument('--ignore-file', metavar='FILE',
+ type=argparse.FileType('r'), dest='ignore_file',
+ help='a file containing a list of revisions to ignore')
+ parser.add_argument('--no-default-ignores', dest='no_default_ignores',
+ help='Do not ignore commits from .git-blame-ignore-revs.')
parser.add_argument('revision', nargs='?', default='HEAD', metavar='REVISION',
help='revision to look at')
parser.add_argument('filename', metavar='FILE', help='filename to blame')
@@ -349,14 +365,21 @@
filename = os.path.normpath(filename)
filename = os.path.normcase(filename)
+ ignored_list = list(args.ignored)
+ if not args.no_default_ignores and os.path.exists(DEFAULT_IGNORE_FILE_NAME):
+ with open(DEFAULT_IGNORE_FILE_NAME) as ignore_file:
+ ignored_list.extend(parse_ignore_file(ignore_file))
+
+ if args.ignore_file:
+ ignored_list.extend(parse_ignore_file(args.ignore_file))
+
ignored = set()
- for c in args.ignored:
+ for c in ignored_list:
try:
ignored.add(git_common.hash_one(c))
except subprocess2.CalledProcessError as e:
- # Custom error message (the message from git-rev-parse is inappropriate).
- stderr.write('fatal: unknown revision \'%s\'.\n' % c)
- return e.returncode
+ # Custom warning string (the message from git-rev-parse is inappropriate).
+ stderr.write('warning: unknown revision \'%s\'.\n' % c)
return hyper_blame(ignored, filename, args.revision, out=stdout, err=stderr)