Added git hyper-blame, a tool that skips unwanted commits in git blame.

Currently, the script requires you to pass the unwanted commits on the
command line, but eventually, you could configure it with a file
(checked into the repo) that provides a fixed set of commits to always
skip (such as commits that do a huge amount of renaming and nothing
else).

BUG=574290

Review URL: https://codereview.chromium.org/1559943003

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@298544 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/git_dates.py b/git_dates.py
new file mode 100644
index 0000000..41cf3ac
--- /dev/null
+++ b/git_dates.py
@@ -0,0 +1,62 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Utility module for dealing with Git timestamps."""
+
+import datetime
+
+
+def timestamp_offset_to_datetime(timestamp, offset):
+  """Converts a timestamp + offset into a datetime.datetime.
+
+  Useful for dealing with the output of porcelain commands, which provide times
+  as timestamp and offset strings.
+
+  Args:
+    timestamp: An int UTC timestamp, or a string containing decimal digits.
+    offset: A str timezone offset. e.g., '-0800'.
+
+  Returns:
+    A tz-aware datetime.datetime for this timestamp.
+  """
+  timestamp = int(timestamp)
+  tz = FixedOffsetTZ.from_offset_string(offset)
+  return datetime.datetime.fromtimestamp(timestamp, tz)
+
+
+def datetime_string(dt):
+  """Converts a tz-aware datetime.datetime into a string in git format."""
+  return dt.strftime('%Y-%m-%d %H:%M:%S %z')
+
+
+# Adapted from: https://docs.python.org/2/library/datetime.html#tzinfo-objects
+class FixedOffsetTZ(datetime.tzinfo):
+  def __init__(self, offset, name):
+    datetime.tzinfo.__init__(self)
+    self.__offset = offset
+    self.__name = name
+
+  def __repr__(self):  # pragma: no cover
+    return '{}({!r}, {!r})'.format(type(self).__name__, self.__offset,
+                                   self.__name)
+
+  @classmethod
+  def from_offset_string(cls, offset):
+    try:
+      hours = int(offset[:-2])
+      minutes = int(offset[-2:])
+    except ValueError:
+      return cls(datetime.timedelta(0), 'UTC')
+
+    delta = datetime.timedelta(hours=hours, minutes=minutes)
+    return cls(delta, offset)
+
+  def utcoffset(self, dt):
+    return self.__offset
+
+  def tzname(self, dt):
+    return self.__name
+
+  def dst(self, dt):
+    return datetime.timedelta(0)