# Copyright (c) 2011-2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Module that handles the processing of patches to the source tree."""

from __future__ import print_function

import calendar
import collections
# We import mock so that we can identify mock.MagicMock instances in tests
# that use mock.
import mock
import os
import random
import re
import time

from chromite.cbuildbot import config_lib
from chromite.cbuildbot import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import git
from chromite.lib import gob_util


site_config = config_lib.GetConfig()


_MAXIMUM_GERRIT_NUMBER_LENGTH = 7
_GERRIT_CHANGE_ID_PREFIX = 'I'
_GERRIT_CHANGE_ID_LENGTH = 40
_GERRIT_CHANGE_ID_TOTAL_LENGTH = (_GERRIT_CHANGE_ID_LENGTH +
                                  len(_GERRIT_CHANGE_ID_PREFIX))
REPO_NAME_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_\-]*(/[a-zA-Z0-9_-]+)*$')
BRANCH_NAME_RE = re.compile(r'^(refs/heads/)?[a-zA-Z0-9_][a-zA-Z0-9_\-]*$')

# Constants for attributes names.
ATTR_REMOTE = 'remote'
ATTR_GERRIT_NUMBER = 'gerrit_number'
ATTR_PROJECT = 'project'
ATTR_BRANCH = 'branch'
ATTR_PROJECT_URL = 'project_url'
ATTR_REF = 'ref'
ATTR_CHANGE_ID = 'change_id'
ATTR_COMMIT = 'commit'
ATTR_PATCH_NUMBER = 'patch_number'
ATTR_OWNER_EMAIL = 'owner_email'
ATTR_FAIL_COUNT = 'fail_count'
ATTR_PASS_COUNT = 'pass_count'
ATTR_TOTAL_FAIL_COUNT = 'total_fail_count'
ATTR_COMMIT_MESSAGE = 'commit_message'

ALL_ATTRS = (
    ATTR_REMOTE,
    ATTR_GERRIT_NUMBER,
    ATTR_PROJECT,
    ATTR_BRANCH,
    ATTR_PROJECT_URL,
    ATTR_REF,
    ATTR_CHANGE_ID,
    ATTR_COMMIT,
    ATTR_PATCH_NUMBER,
    ATTR_OWNER_EMAIL,
    ATTR_FAIL_COUNT,
    ATTR_PASS_COUNT,
    ATTR_TOTAL_FAIL_COUNT,
    ATTR_COMMIT_MESSAGE,
)

def ParseSHA1(text, error_ok=True):
  """Checks if |text| conforms to the SHA1 format and parses it.

  Args:
    text: The string to check.
    error_ok: If set, do not raise an exception if |text| is not a
      valid SHA1.

  Returns:
    If |text| is a valid SHA1, returns |text|.  Otherwise,
    returns None when |error_ok| is set and raises an exception when
    |error_ok| is False.
  """
  valid = git.IsSHA1(text)
  if not error_ok and not valid:
    raise ValueError('%s is not a valid SHA1', text)

  return text if valid else None


def ParseGerritNumber(text, error_ok=True):
  """Checks if |text| conforms to the Gerrit number format and parses it.

  Args:
    text: The string to check.
    error_ok: If set, do not raise an exception if |text| is not a
      valid Gerrit number.

  Returns:
    If |text| is a valid Gerrit number, returns |text|.  Otherwise,
    returns None when |error_ok| is set and raises an exception when
    |error_ok| is False.
  """
  valid = text.isdigit() and len(text) <= _MAXIMUM_GERRIT_NUMBER_LENGTH
  if not error_ok and not valid:
    raise ValueError('%s is not a valid Gerrit number', text)

  return text if valid else None


def ParseChangeID(text, error_ok=True):
  """Checks if |text| conforms to the change-ID format and parses it.

  Change-ID is a string that starts with I/i. E.g.
    I47ea30385af60ae4cc2acc5d1a283a46423bc6e1

  Args:
    text: The string to check.
    error_ok: If set, do not raise an exception if |text| is not a
      valid change-ID.

  Returns:
    If |text| is a valid change-ID, returns |text|.  Otherwise,
    returns None when |error_ok| is set and raises an exception when
    |error_ok| is False.
  """
  valid = (text.startswith(_GERRIT_CHANGE_ID_PREFIX) and
           len(text) == _GERRIT_CHANGE_ID_TOTAL_LENGTH and
           git.IsSHA1(text[len(_GERRIT_CHANGE_ID_PREFIX):].lower()))

  if not error_ok and not valid:
    raise ValueError('%s is not a valid change-ID', text)

  return text if valid else None


FullChangeId = collections.namedtuple(
    'FullChangeId', ('project', 'branch', 'change_id'))


def ParseFullChangeID(text, error_ok=True):
  """Checks if |text| conforms to the full change-ID format and parses it.

  Full change-ID format: project~branch~change-id. E.g.
    chromiumos/chromite~master~I47ea30385af60ae4cc2acc5d1a283a46423bc6e1

  Args:
    text: The string to check.
    error_ok: If set, do not raise an exception if |text| is not a
      valid full change-ID.

  Returns:
    If |text| is a valid full change-ID, returns (project, branch,
    change_id).  Otherwise, returns None when |error_ok| is set and
    raises an exception when |error_ok| is False.
  """
  fields = text.split('~')
  if not len(fields) == 3:
    if not error_ok:
      raise ValueError('%s is not a valid full change-ID', text)

    return None

  project, branch, change_id = fields
  if (not REPO_NAME_RE.match(project) or
      not BRANCH_NAME_RE.match(branch) or
      not ParseChangeID(change_id)):
    if not error_ok:
      raise ValueError('%s is not a valid full change-ID', text)

    return None

  return FullChangeId(project, branch, change_id)


class PatchException(Exception):
  """Base exception class all patch exception derive from."""

  # Unless instances override it, default all exceptions to ToT.
  inflight = False

  def __init__(self, patch, message=None):
    if (not isinstance(patch, GitRepoPatch) and
        not isinstance(patch, mock.MagicMock)):
      raise TypeError(
          'Patch must be a GitRepoPatch derivative; got type %s: %r'
          % (type(patch), patch))
    Exception.__init__(self)
    self.patch = patch
    self.message = message
    self.args = (patch,)
    if message is not None:
      self.args += (message,)

  def ShortExplanation(self):
    """Print a short explanation of why the patch failed.

    Explanations here should be suitable for inclusion in a sentence
    starting with the CL number. This is useful for writing nice error
    messages about dependency errors.
    """
    return 'failed: %s' % (self.message,)

  def __str__(self):
    return '%s %s' % (self.patch.PatchLink(), self.ShortExplanation())


class ApplyPatchException(PatchException):
  """Exception thrown if we fail to apply a patch."""

  def __init__(self, patch, message=None, inflight=False, trivial=False,
               files=()):
    PatchException.__init__(self, patch, message=message)
    self.inflight = inflight
    self.trivial = trivial
    self.files = files = tuple(files)
    # Reset args; else serialization can break.
    self.args = (patch, message, inflight, trivial, files)

  def _StringifyInflight(self):
    return 'the current patch series' if self.inflight else 'ToT'

  def _StringifyFilenames(self):
    """Stringify our list of filenames for presentation in Gerrit."""
    # Prefix each filename with a hyphen so that Gerrit will format it as an
    # unordered list.
    return '\n\n'.join('- %s' % x for x in self.files)

  def ShortExplanation(self):
    s = 'conflicted with %s' % (self._StringifyInflight(),)
    if self.trivial:
      s += (' because file content merging is disabled for this '
            'project.')
    else:
      s += '.'
    if self.files:
      s += ('\n\nThe conflicting files are amongst:\n\n'
            '%s' % (self._StringifyFilenames(),))
    if self.message:
      s += '\n\n%s' % (self.message,)
    return s


class EbuildConflict(ApplyPatchException):
  """Exception thrown if two CLs delete the same ebuild."""

  def __init__(self, patch, inflight, ebuilds):
    ApplyPatchException.__init__(self, patch, inflight=inflight, files=ebuilds)
    self.args = (patch, inflight, ebuilds)

  def ShortExplanation(self):
    return ('deletes an ebuild that is not present anymore. For this reason, '
            'we refuse to merge your change.\n\n'
            'When you rebase your change, please take into account that the '
            'following ebuilds have been uprevved or deleted:\n\n'
            '%s' % (self._StringifyFilenames()))


class PatchIsEmpty(ApplyPatchException):
  """Exception thrown if we try to apply an empty patch"""

  def ShortExplanation(self):
    return 'had no changes after rebasing to %s.' % (
        self._StringifyInflight(),)


class DependencyError(PatchException):
  """Thrown when a change cannot be applied due to a failure in a dependency."""

  def __init__(self, patch, error):
    """Initialize the error object.

    Args:
      patch: The GitRepoPatch instance that this exception concerns.
      error: A PatchException object that can be stringified to describe
        the error.
    """
    PatchException.__init__(self, patch)
    self.inflight = error.inflight
    self.error = error
    self.args = (patch, error)

  def ShortExplanation(self):
    link = self.error.patch.PatchLink()
    return 'depends on %s, which %s' % (link, self.error.ShortExplanation())


class BrokenCQDepends(PatchException):
  """Raised if a patch has a CQ-DEPEND line that is ill formated."""

  def __init__(self, patch, text, msg=None):
    PatchException.__init__(self, patch)
    self.text = text
    self.msg = msg
    self.args = (patch, text, msg)

  def ShortExplanation(self):
    s = 'has a malformed CQ-DEPEND target: %s' % (self.text,)
    if self.msg is not None:
      s += '; %s' % (self.msg,)
    return s


class BrokenChangeID(PatchException):
  """Raised if a patch has an invalid or missing Change-ID."""

  def __init__(self, patch, message, missing=False):
    PatchException.__init__(self, patch)
    self.message = message
    self.missing = missing
    self.args = (patch, message, missing)

  def ShortExplanation(self):
    return 'has a broken ChangeId: %s' % (self.message,)


class ChangeMatchesMultipleCheckouts(PatchException):
  """Raised if the given change matches multiple checkouts."""

  def ShortExplanation(self):
    return ('matches multiple checkouts. Does the manifest check out the '
            'same project and branch to different locations?')


class ChangeNotInManifest(PatchException):
  """Raised if we try to apply a not-in-manifest change."""

  def ShortExplanation(self):
    return 'could not be found in the repo manifest.'


class PatchNotMergeable(PatchException):
  """Raised if a patch is not mergeable."""

  def __init__(self, patch, reason):
    PatchException.__init__(self, patch)
    self.reason = str(reason)
    self.args = (patch, reason)

  def ShortExplanation(self):
    return self.reason


def MakeChangeId(unusable=False):
  """Create a random Change-Id.

  Args:
    unusable: If set to True, return a Change-Id like string that gerrit
      will explicitly fail on.  This is primarily used for internal ids,
      as a fallback when a Change-Id could not be parsed.
  """
  s = '%x' % (random.randint(0, 2 ** 160),)
  s = s.rjust(_GERRIT_CHANGE_ID_LENGTH, '0')
  if unusable:
    return 'Fake-ID %s' % s
  return '%s%s' % (_GERRIT_CHANGE_ID_PREFIX, s)


class PatchCache(object):
  """Dict-like object used for tracking a group of patches.

  This is usable both for existence checks against given string
  deps, and for change querying.
  """

  def __init__(self, initial=()):
    self._dict = {}
    self.Inject(*initial)

  def Inject(self, *args):
    """Inject a sequence of changes into this cache."""
    for change in args:
      self.InjectCustomKeys(change.LookupAliases(), change)

  def InjectCustomKeys(self, keys, change):
    """Inject a change w/ a list of keys.  Generally you want Inject instead.

    Args:
      keys: A list of keys to update.
      change: The change to update the keys to.
    """
    for key in keys:
      self._dict[str(key)] = change

  def _GetAliases(self, value):
    if hasattr(value, 'LookupAliases'):
      return value.LookupAliases()
    elif not isinstance(value, basestring):
      # This isn't needed in production code; it however is
      # rather useful to flush out bugs in test code.
      raise ValueError("Value %r isn't a string" % (value,))
    return [value]

  def Remove(self, *args):
    """Remove a change from this cache."""
    for change in args:
      for alias in self._GetAliases(change):
        self._dict.pop(alias, None)

  def __iter__(self):
    return iter(set(self._dict.itervalues()))

  def __getitem__(self, key):
    """If the given key exists, return the Change, else None."""
    for alias in self._GetAliases(key):
      val = self._dict.get(alias)
      if val is not None:
        return val
    return None

  def __contains__(self, key):
    return self[key] is not None

  def copy(self):
    """Return a copy of this cache."""
    return self.__class__(list(self))


def StripPrefix(text):
  """Strips the leading '*' for internal change names.

  Args:
    text: text to examine.

  Returns:
    A tuple of the corresponding remote and the stripped text.
  """
  remote = site_config.params.EXTERNAL_REMOTE
  prefix = site_config.params.INTERNAL_CHANGE_PREFIX
  if text.startswith(prefix):
    text = text[len(prefix):]
    remote = site_config.params.INTERNAL_REMOTE

  return remote, text


def AddPrefix(patch, text):
  """Add the leading '*' to |text| if applicable.

  Examines patch.remote and adds the prefix to text if applicable.

  Args:
    patch: A PatchQuery object to examine.
    text: The text to add prefix to.

  Returns:
    |text| with an added prefix for internal patches; otherwise, returns text.
  """
  return '%s%s' % (site_config.params.CHANGE_PREFIX[patch.remote], text)


def ParsePatchDep(text, no_change_id=False, no_sha1=False,
                  no_full_change_id=False, no_gerrit_number=False):
  """Parses a given patch dependency and convert it to a PatchQuery object.

  Parse user-given dependency (e.g. from the CQ-DEPEND line in the
  commit message) and returns a PatchQuery object with the relevant
  information of the dependency.

  Args:
    text: The text to parse.
    no_change_id: Do not allow change-ID.
    no_sha1: Do not allow SHA1.
    no_full_change_id: Do not allow full change-ID.
    no_gerrit_number: Do not allow gerrit_number.

  Returns:
    A PatchQuery object.
  """
  original_text = text
  if not text:
    raise ValueError('ParsePatchDep invoked with an empty value: %r'
                     % (text,))
  # Deal w/ CL: targets.
  if text.upper().startswith('CL:'):
    if not text.startswith('CL:'):
      raise ValueError(
          "ParsePatchDep: 'CL:' must be upper case: %r"
          % (original_text,))
    text = text[3:]

  # Strip the prefix to determine the remote.
  remote, text = StripPrefix(text)

  parsed = ParseFullChangeID(text)
  if parsed:
    if no_full_change_id:
      raise ValueError(
          'ParsePatchDep: Full Change-ID is not allowed: %r.' % original_text)

    return PatchQuery(remote, project=parsed.project,
                      tracking_branch=parsed.branch, change_id=parsed.change_id)

  parsed = ParseChangeID(text)
  if parsed:
    if no_change_id:
      raise ValueError(
          'ParsePatchDep: Change-ID is not allowed: %r.' % original_text)

    return PatchQuery(remote, change_id=parsed)

  parsed = ParseGerritNumber(text)
  if parsed:
    if no_gerrit_number:
      raise ValueError(
          'ParsePatchDep: Gerrit number is not allowed: %r.' % original_text)

    return PatchQuery(remote, gerrit_number=parsed)

  parsed = ParseSHA1(text)
  if parsed:
    if no_sha1:
      raise ValueError(
          'ParsePatchDep: SHA1 is not allowed: %r.' % original_text)

    return PatchQuery(remote, sha1=parsed)

  raise ValueError('Cannot parse the dependency: %s' % original_text)


def GetOptionLinesFromCommitMessage(commit_message, option_re):
  """Finds lines in |commit_message| that start with |option_re|.

  Args:
    commit_message: (str) Text of the commit message.
    option_re: (str) regular expression to match the key identifying this
               option. Additionally, any whitespace surrounding the option
               is ignored.

  Returns:
    list of line values that matched the option (with the option stripped
    out) if at least 1 line matched the option (even if it provided no
    valuse). None if no lines of the message matched the option.
  """
  option_lines = []
  matched = False
  lines = commit_message.splitlines()[2:]
  for line in lines:
    line = line.strip()
    if re.match(option_re, line):
      matched = True
      line = re.sub(option_re, '', line, count=1).strip()
      if line:
        option_lines.append(line)

  if matched:
    return option_lines
  else:
    return None


# TODO(akeshet): Refactor CQ-DEPEND parsing logic to use general purpose
# GetOptionFromCommitMessage.
def GetPaladinDeps(commit_message):
  """Get the paladin dependencies for the given |commit_message|."""
  PALADIN_DEPENDENCY_RE = re.compile(r'^([ \t]*CQ.?DEPEND.)(.*)$',
                                     re.MULTILINE | re.IGNORECASE)
  PATCH_RE = re.compile('[^, ]+')
  EXPECTED_PREFIX = 'CQ-DEPEND='
  matches = PALADIN_DEPENDENCY_RE.findall(commit_message)
  dependencies = []
  for prefix, match in matches:
    if prefix != EXPECTED_PREFIX:
      msg = 'Expected %r, but got %r' % (EXPECTED_PREFIX, prefix)
      raise ValueError(msg)
    for chunk in PATCH_RE.findall(match):
      chunk = ParsePatchDep(chunk, no_sha1=True)
      if chunk not in dependencies:
        dependencies.append(chunk)
  return dependencies


class PatchQuery(object):
  """Store information about a patch.

  This stores information about a patch used to query Gerrit and/or
  our internal PatchCache. It is mostly used to describe a patch
  dependency.

  It is is intended to match a single patch. If a user specified a
  non-full change id then it might match multiple patches. If a user
  specified an invalid change id then it might not match any patches.
  """

  def __init__(self, remote, project=None, tracking_branch=None, change_id=None,
               sha1=None, gerrit_number=None):
    """Initializes a PatchQuery instance.

    Args:
      remote: The remote git instance path, defined in constants.CROS_REMOTES.
      project: The name of the project that the patch applies to.
      tracking_branch: The remote branch of the project the patch applies to.
      change_id: The Gerrit Change-ID representing this patch.
      sha1: The sha1 of the commit. This *must* be accurate
      gerrit_number: The Gerrit number of the patch.
    """
    self.remote = remote
    self.tracking_branch = None
    if tracking_branch:
      self.tracking_branch = os.path.basename(tracking_branch)
    self.project = project
    self.sha1 = None if sha1 is None else ParseSHA1(sha1)
    self.tree_hash = None
    self.change_id = None if change_id is None else ParseChangeID(change_id)
    self.gerrit_number = (None if gerrit_number is None else
                          ParseGerritNumber(gerrit_number))
    self.id = self.full_change_id = None
    self._SetFullChangeID()
    # self.id is the only attribute with the internal prefix (*) if
    # applicable. All other atttributes are strictly external format.
    self._SetID()

  def _SetFullChangeID(self):
    """Set the unique full Change-ID if possible."""
    if (self.project is not None and
        self.tracking_branch is not None and
        self.change_id is not None):
      self.full_change_id = '%s~%s~%s' % (
          self.project, self.tracking_branch, self.change_id)

  def _SetID(self, override_value=None):
    """Set the unique ID to be used internally, if possible."""
    if override_value is not None:
      self.id = override_value
      return

    if not self.full_change_id:
      self._SetFullChangeID()

    if self.full_change_id:
      self.id = AddPrefix(self, self.full_change_id)

    elif self.sha1:
      # We assume sha1 is unique, but in rare cases (e.g. two branches with
      # the same history) it is not. We don't handle that.
      self.id = '%s%s' % (site_config.params.CHANGE_PREFIX[self.remote],
                          self.sha1)

  def LookupAliases(self):
    """Returns the list of lookup keys to query a PatchCache.

    Each key has to be unique for the patch. If no unique key can be
    generated yet (because of incomplete patch information), we'd
    rather return None to avoid retrieving incorrect patch from the
    cache.
    """
    l = []
    if self.gerrit_number:
      l.append(self.gerrit_number)

    # Note that change-ID alone is not unique. Use full change-id here.
    if self.full_change_id:
      l.append(self.full_change_id)

    # Note that in rare cases (two branches with the same history),
    # the commit hash may not be unique. We don't handle that.
    if self.sha1:
      l.append(self.sha1)

    return ['%s%s' % (site_config.params.CHANGE_PREFIX[self.remote], x)
            for x in l if x is not None]

  def ToGerritQueryText(self):
    """Generate a text used to query Gerrit.

    This text may not be unique because the lack of information from
    user-specified dependencies (crbug.com/354734). In which cases,
    the Gerrit query would fail.
    """
    # Try to return a unique ID if possible.
    if self.gerrit_number:
      return self.gerrit_number
    elif self.full_change_id:
      return self.full_change_id
    elif self.sha1:
      # SHA1 may not not be unique, but we don't handle that here.
      return self.sha1
    elif self.change_id:
      # Fall back to use Change-Id, which is not unique.
      return self.change_id
    else:
      # We cannot query without at least one of the three fields. A
      # special case is UploadedLocalPatch which has none of the
      # above, but also is not used for query.
      raise ValueError(
          'We do not have enough information to generate a Gerrit query. '
          'At least one of the following fields needs to be set: Change-Id, '
          'Gerrit number, or sha1')

  def __hash__(self):
    """Returns a hash to be used in a set or a list."""
    if self.id:
      return hash(self.id)
    else:
      return hash((self.remote, self.project, self.tracking_branch,
                   self.gerrit_number, self.change_id, self.sha1))

  def __eq__(self, other):
    """Defines when two PatchQuery objects are considered equal."""
    # We allow comparing against a string to make testing easier.
    if isinstance(other, basestring):
      return self.id == other

    if self.id is not None:
      return self.id == getattr(other, 'id', None)

    return ((self.remote, self.project, self.tracking_branch,
             self.gerrit_number, self.change_id, self.sha1) ==
            (other.remote, other.project, other.tracking_branch,
             other.gerrit_number, other.change_id, other.sha1))


class GitRepoPatch(PatchQuery):
  """Representing a patch from a branch of a local or remote git repository."""

  # Note the selective case insensitivity; gerrit allows only this.
  # TOOD(ferringb): back VALID_CHANGE_ID_RE down to {8,40}, requires
  # ensuring CQ's internals can do the translation (almost can now,
  # but will fail in the case of a CQ-DEPEND on a change w/in the
  # same pool).
  pattern = (r'^' + re.escape(_GERRIT_CHANGE_ID_PREFIX) + r'[0-9a-fA-F]{' +
             re.escape(str(_GERRIT_CHANGE_ID_LENGTH)) + r'}$')
  _STRICT_VALID_CHANGE_ID_RE = re.compile(pattern)
  _GIT_CHANGE_ID_RE = re.compile(r'^Change-Id:[\t ]*(\w+)\s*$',
                                 re.I | re.MULTILINE)

  def __init__(self, project_url, project, ref, tracking_branch, remote,
               sha1=None, change_id=None):
    """Initialization of abstract Patch class.

    Args:
      project_url: The url of the git repo (can be local or remote) to pull the
                   patch from.
      project: See PatchQuery for documentation.
      ref: The refspec to pull from the git repo.
      tracking_branch: See PatchQuery for documentation.
      remote: See PatchQuery for documentation.
      sha1: The sha1 of the commit, if known. This *must* be accurate.  Can
        be None if not yet known- in which case Fetch will update it.
      change_id: See PatchQuery for documentation.
    """
    super(GitRepoPatch, self).__init__(remote, project=project,
                                       tracking_branch=tracking_branch,
                                       change_id=change_id,
                                       sha1=sha1, gerrit_number=None)

    # git_remote_url is the url of the remote git repo that this patch
    # belongs to. Differs from project_url as that may point to a local
    # repo or a gerrit review repo.
    self.git_remote_url = '%s/%s' % (
        site_config.params.GIT_REMOTES.get(remote), project)
    self.project_url = project_url
    self.commit_message = None
    self._subject_line = None
    self.ref = ref
    self._is_fetched = set()
    self._committer_email = None
    self._committer_name = None
    self._commit_message = None

  @property
  def commit_message(self):
    return self._commit_message

  @commit_message.setter
  def commit_message(self, value):
    self._commit_message = self._AddFooters(value) if value else value

  @property
  def internal(self):
    """Whether patch is to an internal cros project."""
    return self.remote == site_config.params.INTERNAL_REMOTE

  def _GetFooters(self, msg):
    """Get the Git footers of the specified commit message.

    Args:
      msg: A commit message

    Returns:
      The parsed footers from the commit message.  Footers are
      lines of the form 'key: value' and are at the end of the commit
      message in a separate paragraph.  We return a list of pairs like
      ('key', 'value').
    """
    footers = []
    data = re.split(r'\n{2,}', msg.rstrip('\n'))[-1]
    for line in data.splitlines():
      m = re.match(r'([A-Za-z0-9-]+): *(.*)', line.rstrip('\n'))
      if m:
        footers.append(m.groups())
    return footers

  def _AddFooters(self, msg):
    """Ensure that commit messages have a change ID.

    Args:
      msg: The commit message.

    Returns:
      The modified commit message with necessary Gerrit footers.
    """
    if not msg:
      msg = '<no commit message provided>'

    if msg[-1] != '\n':
      msg += '\n'

    # This function is adapted from the version in Gerrit:
    # goto/createCherryPickCommitMessage
    old_footers = self._GetFooters(msg)

    if not old_footers:
      # Doesn't end in a "Signed-off-by: ..." style line? Add another line
      # break to start a new paragraph for the reviewed-by tag lines.
      msg += '\n'

    # This replicates the behavior of
    # goto/createCherryPickCommitMessage, but can result in multiple
    # Change-Id footers.  We should consider changing this behavior.
    if ('Change-Id', self.change_id) not in old_footers and self.change_id:
      msg += 'Change-Id: %s\n' % self.change_id

    return msg

  def _PullData(self, rev, git_repo):
    """Returns info about a commit object in the local repository.

    Args:
      rev: The commit to find information about
      git_repo: The path of the local git repository.

    Returns:
      A 6-tuple of (sha1, tree_hash, commit subject, commit message,
      committer email, committer name).
    """
    f = '%H%x00%T%x00%s%x00%B%x00%ce%x00%cn'
    cmd = ['log', '--pretty=format:%s' % f, '-n1', rev]
    ret = git.RunGit(git_repo, cmd, error_code_ok=True)
    # TODO(phobbs): this should probably use a namedtuple...
    if ret.returncode != 0:
      return None, None, None, None, None, None
    output = ret.output.split('\0')
    if len(output) != 6:
      return None, None, None, None, None, None
    return [unicode(x.strip(), 'ascii', 'ignore') for x in output]

  def UpdateMetadataFromRepo(self, git_repo, sha1):
    """Update this this object's metadata given a sha1.

    This updates various internal fields such as the committer name and email,
    the commit message, tree hash, etc.

    Raises a PatchException if the found sha1 differs from self.sha1.

    Args:
      git_repo: The path to the git repository that this commit exists in.
      sha1: The sha1 of the commit.  If None, assumes it was just fetched and
        uses "FETCH_HEAD".

    Returns:
      The sha1 of the commit.
    """
    sha1 = sha1 or 'FETCH_HEAD'
    sha1, tree_hash, subject, msg, email, name = self._PullData(sha1, git_repo)
    sha1 = ParseSHA1(sha1, error_ok=False)

    if self.sha1 is not None and sha1 != self.sha1:
      # Even if we know the sha1, still do a sanity check to ensure we
      # actually just fetched it.
      raise PatchException(self,
                           'Patch %s specifies sha1 %s, yet in fetching from '
                           '%s we could not find that sha1.  Internal error '
                           'most likely.' % (self, self.sha1, self.ref))

    self._committer_email = email
    self._committer_name = name
    self.sha1 = sha1
    self.tree_hash = tree_hash
    self.commit_message = msg
    self._EnsureId(self.commit_message)
    self._subject_line = subject
    self._is_fetched.add(git_repo)
    return self.sha1

  def HasBeenFetched(self, git_repo):
    """Whether this patch has already exists locally in `git_repo`

    Args:
      git_repo: The git repository to fetch this patch into.

    Returns:
      If it exists, the sha1 of this patch in `git_repo`.
    """
    git_repo = os.path.normpath(git_repo)
    if git_repo in self._is_fetched:
      return self.sha1

    # See if we've already got the object.
    if self.sha1 is not None:
      return self._PullData(self.sha1, git_repo)[0]

  def Fetch(self, git_repo):
    """Fetch this patch into the given git repository.

    FETCH_HEAD is implicitly reset by this operation.  Additionally,
    if the sha1 of the patch was not yet known, it is pulled and stored
    on this object and the git_repo is updated w/ the requested git
    object.

    While doing so, we'll load the commit message and Change-Id if not
    already known.

    Finally, if the sha1 is known and it's already available in the target
    repository, this will skip the actual fetch operation (it's unneeded).

    Args:
      git_repo: The git repository to fetch this patch into.

    Returns:
      The sha1 of the patch.
    """
    sha1 = self.HasBeenFetched(git_repo)

    if sha1 is None:
      git.RunGit(git_repo, ['fetch', '-f', self.project_url, self.ref],
                 print_cmd=True)

    return self.UpdateMetadataFromRepo(git_repo, sha1=sha1 or self.sha1)

  def GetDiffStatus(self, git_repo):
    """Isolate the paths and modifications this patch induces.

    Note that detection of file renaming is explicitly turned off.
    This is intentional since the level of rename detection can vary
    by user configuration, and trying to have our code specify the
    minimum level is fairly messy from an API perspective.

    Args:
      git_repo: Git repository to operate upon.

    Returns:
      A dictionary of path -> modification_type tuples.  See
      `git log --help`, specifically the --diff-filter section for details.
    """

    self.Fetch(git_repo)

    try:
      lines = git.RunGit(git_repo, ['diff', '--no-renames', '--name-status',
                                    '%s^..%s' % (self.sha1, self.sha1)])
    except cros_build_lib.RunCommandError as e:
      # If we get a 128, that means git couldn't find the the parent of our
      # sha1- meaning we're the first commit in the repository (there is no
      # parent).
      if e.result.returncode != 128:
        raise
      return {}
    lines = lines.output.splitlines()
    return dict(line.split('\t', 1)[::-1] for line in lines)

  def _AmendCommitMessage(self, git_repo):
    """"Amend the commit and update our sha1 with the new commit."""
    git.RunGit(git_repo, ['commit', '--amend', '-m', self.commit_message])
    self.sha1 = ParseSHA1(self._PullData('HEAD', git_repo)[0], error_ok=False)

  def CherryPick(self, git_repo, trivial=False, inflight=False,
                 leave_dirty=False):
    """Attempts to cherry-pick the given rev into branch.

    Args:
      git_repo: The git repository to operate upon.
      trivial: Only allow trivial merges when applying change.
      inflight: If true, changes are already applied in this branch.
      leave_dirty: If True, if a CherryPick fails leaves partial commit behind.

    Raises:
      A ApplyPatchException if the request couldn't be handled.
    """
    # Note the --ff; we do *not* want the sha1 to change unless it
    # has to.
    cmd = ['cherry-pick', '--strategy', 'resolve', '--ff']
    if trivial:
      cmd += ['-X', 'trivial']
    cmd.append(self.sha1)

    reset_target = None if leave_dirty else 'HEAD'
    try:
      git.RunGit(git_repo, cmd, capture_output=False)
      self._AmendCommitMessage(git_repo)
      reset_target = None
      return
    except cros_build_lib.RunCommandError as error:
      ret = error.result.returncode
      if ret not in (1, 2):
        logging.error('Unknown cherry-pick exit code %s; %s', ret, error)
        raise ApplyPatchException(
            self, inflight=inflight,
            message=('Unknown exit code %s returned from cherry-pick '
                     'command: %s' % (ret, error)))
      elif ret == 1:
        # This means merge resolution was fine, but there was content conflicts.
        # If there are no conflicts, then this is caused by the change already
        # being merged.
        result = git.RunGit(git_repo,
                            ['diff', '--name-only', '--diff-filter=U'])

        # Output is one line per filename.
        conflicts = result.output.splitlines()
        if not conflicts:
          # No conflicts means the git repo is in a pristine state.
          reset_target = None
          raise PatchIsEmpty(self, inflight=inflight)

        # Making it here means that it wasn't trivial, nor was it already
        # applied.
        assert not trivial
        raise ApplyPatchException(self, inflight=inflight, files=conflicts)

      # ret=2 handling, this deals w/ trivial conflicts; including figuring
      # out if it was trivial induced or not.
      if not trivial:
        logging.error('The git tree may be corrupted.')
        logging.error('If the git error is "unable to read tree", '
                      'please clean up this repo.')
        raise

      # Here's the kicker; trivial conflicts can mask content conflicts.
      # We would rather state if it's a content conflict since in solving the
      # content conflict, the trivial conflict is solved.  Thus this
      # second run, where we let the exception fly through if one occurs.
      # Note that a trivial conflict means the tree is unmodified; thus
      # no need for cleanup prior to this invocation.
      reset_target = None
      self.CherryPick(git_repo, trivial=False, inflight=inflight)
      # Since it succeeded, we need to rewind.
      reset_target = 'HEAD^'

      raise ApplyPatchException(self, trivial=True, inflight=inflight)
    finally:
      if reset_target is not None:
        git.RunGit(git_repo, ['reset', '--hard', reset_target],
                   error_code_ok=True)

  def Apply(self, git_repo, upstream, revision=None, trivial=False):
    """Apply patch into a standalone git repo.

    The git repo does not need to be part of a repo checkout.

    Args:
      git_repo: The git repository to operate upon.
      revision: Revision to attach the tracking branch to.
      upstream: The branch to base the patch on.
      trivial: Only allow trivial merges when applying change.
    """

    self.Fetch(git_repo)

    logging.info('Attempting to cherry-pick change %s', self)

    # If the patch branch exists use it, otherwise create it and switch to it.
    if git.DoesCommitExistInRepo(git_repo, constants.PATCH_BRANCH):
      git.RunGit(git_repo, ['checkout', '-f', constants.PATCH_BRANCH])
    else:
      git.RunGit(git_repo,
                 ['checkout', '-b', constants.PATCH_BRANCH, '-t', upstream])
      if revision:
        git.RunGit(git_repo, ['reset', '--hard', revision])

    # Figure out if we're inflight.  At this point, we assume that the branch
    # is checked out and rebased onto upstream.  If HEAD differs from upstream,
    # then there are already other patches that have been applied.
    upstream, head = [
        git.RunGit(git_repo, ['rev-list', '-n1', x]).output.strip()
        for x in (upstream, 'HEAD')]
    inflight = (head != upstream)

    self._FindEbuildConflicts(git_repo, upstream, inflight=inflight)

    do_checkout = True
    try:
      self.CherryPick(git_repo, trivial=trivial, inflight=inflight)
      do_checkout = False
      return
    except ApplyPatchException:
      if not inflight:
        raise
      git.RunGit(git_repo, ['checkout', '-f', '--detach', upstream])

      self.CherryPick(git_repo, trivial=trivial, inflight=False)
      # Making it here means that it was an inflight issue; throw the original.
      raise
    finally:
      # Ensure we're on the correct branch on the way out.
      if do_checkout:
        git.RunGit(git_repo, ['checkout', '-f', constants.PATCH_BRANCH],
                   error_code_ok=True)

  def ApplyAgainstManifest(self, manifest, trivial=False):
    """Applies the patch against the specified manifest.

      manifest: A ManifestCheckout object which is used to discern which
        git repo to patch, what the upstream branch should be, etc.
      trivial:  Only allow trivial merges when applying change.

    Raises:
      ApplyPatchException: If the patch failed to apply.
    """
    checkout = self.GetCheckout(manifest)
    revision = checkout.get('revision')
    # revision might be a branch which is written as it would appear on the
    # remote. If so, rewrite it as a local reference to the remote branch.
    # For example, refs/heads/master might become refs/remotes/cros/master.
    if revision and not git.IsSHA1(revision):
      revision = 'refs/remotes/%s/%s' % \
          (checkout['remote'], git.StripRefs(revision))
    upstream = checkout['tracking_branch']
    self.Apply(checkout.GetPath(absolute=True), upstream, revision=revision,
               trivial=trivial)

  def GerritDependencies(self):
    """Returns a list of Gerrit change numbers that this patch depends on.

    Ordinary patches have no Gerrit-style dependencies since they're not
    from Gerrit at all. See GerritPatch.GerritDependencies instead.
    """
    return []

  def _EnsureId(self, commit_message):
    """Ensure we have a usable Change-Id.

    This will parse the Change-Id out of the given commit message;
    if it cannot find one, it logs a warning and creates a fake ID.

    By its nature, that fake ID is useless- it's created to simplify
    API usage for patch consumers. If CQ were to see and try operating
    on one of these, it would fail for example.
    """
    if self.id is not None:
      return self.id

    try:
      self.change_id = self._ParseChangeId(commit_message)
    except BrokenChangeID:
      logging.warning(
          'Change %s, sha1 %s lacks a change-id in its commit '
          'message.  CQ-DEPEND against this rev may not work, nor '
          'will any gerrit querying.  Please add the appropriate '
          'Change-Id into the commit message to resolve this.',
          self, self.sha1)
      self._SetID(self.sha1)
    else:
      self._SetID()

  def _ParseChangeId(self, data):
    """Parse a Change-Id out of a block of text.

    Note that the returned content is *not* ran through FormatChangeId;
    this is left up to the invoker.
    """
    # Grab just the last pararaph.
    git_metadata = re.split(r'\n{2,}', data.rstrip())[-1]
    change_id_match = self._GIT_CHANGE_ID_RE.findall(git_metadata)
    if not change_id_match:
      raise BrokenChangeID(self, 'Missing Change-Id in %s' % (data,),
                           missing=True)

    # Now, validate it.  This has no real effect on actual gerrit patches,
    # but for local patches the validation is useful for general sanity
    # enforcement.
    change_id_match = change_id_match[-1]
    # Note that since we're parsing it from basically a commit message,
    # the gerrit standard format is required- no internal markings.
    if not self._STRICT_VALID_CHANGE_ID_RE.match(change_id_match):
      raise BrokenChangeID(self, change_id_match)

    return ParseChangeID(change_id_match)

  def PaladinDependencies(self, git_repo):
    """Returns an ordered list of dependencies based on the Commit Message.

    Parses the Commit message for this change looking for lines that follow
    the format:

    CQ-DEPEND=change_num+ e.g.

    A commit which depends on a couple others.

    BUG=blah
    TEST=blah
    CQ-DEPEND=10001,10002
    """
    dependencies = []
    logging.debug('Checking for CQ-DEPEND dependencies for change %s', self)

    # Only fetch the commit message if needed.
    if self.commit_message is None:
      self.Fetch(git_repo)

    try:
      dependencies = GetPaladinDeps(self.commit_message)
    except ValueError as e:
      raise BrokenCQDepends(self, str(e))

    if dependencies:
      logging.debug('Found %s Paladin dependencies for change %s',
                    dependencies, self)
    return dependencies

  def _FindEbuildConflicts(self, git_repo, upstream, inflight=False):
    """Verify that there are no ebuild conflicts in the given |git_repo|.

    When an ebuild is uprevved, git treats the uprev as a "delete" and an "add".
    If a developer writes a CL to delete an ebuild, and the CQ uprevs the ebuild
    in the mean time, the ebuild deletion is silently lost, because git does
    not flag the double-delete as a conflict. Instead the CQ attempts to test
    the CL and it ends up breaking the CQ.

    Args:
      git_repo: The directory to examine.
      upstream: The upstream git revision.
      inflight: Whether we currently have patches applied to this repository.
    """
    ebuilds = [path for (path, mtype) in
               self.GetDiffStatus(git_repo).iteritems()
               if mtype == 'D' and path.endswith('.ebuild')]

    conflicts = self._FindMissingFiles(git_repo, 'HEAD', ebuilds)
    if not conflicts:
      return

    if inflight:
      # If we're inflight, test against ToT for an accurate error message.
      tot_conflicts = self._FindMissingFiles(git_repo, upstream, ebuilds)
      if tot_conflicts:
        inflight = False
        conflicts = tot_conflicts

    raise EbuildConflict(self, inflight=inflight, ebuilds=conflicts)

  def _FindMissingFiles(self, git_repo, tree_revision, files):
    """Return a list of the |files| that are missing in |tree_revision|.

    Args:
      git_repo: Git repository to work in.
      tree_revision: Revision of the tree to use.
      files: Files to look for.

    Returns:
      A list of the |files| that are missing in |tree_revision|.
    """
    if not files:
      return []

    cmd = ['ls-tree', '--full-name', '--name-only', '-z', tree_revision, '--']
    output = git.RunGit(git_repo, cmd + files, error_code_ok=True).output
    existing_filenames = output.split('\0')[:-1]
    return [x for x in files if x not in existing_filenames]

  def GetCheckout(self, manifest, strict=True):
    """Get the ProjectCheckout associated with this patch.

    Args:
      manifest: A ManifestCheckout object.
      strict: If the change refers to a project/branch that is not in the
        manifest, raise a ChangeNotInManifest error.

    Raises:
      ChangeMatchesMultipleCheckouts if there are multiple checkouts that
      match this change.
    """
    checkouts = manifest.FindCheckouts(self.project, self.tracking_branch,
                                       only_patchable=True)
    if len(checkouts) != 1:
      if len(checkouts) > 1:
        raise ChangeMatchesMultipleCheckouts(self)
      elif strict:
        raise ChangeNotInManifest(self)
      return None

    return checkouts[0]

  def PatchLink(self):
    """Return a CL link for this patch."""
    # GitRepoPatch instances don't have a CL link, so just return the string
    # representation.
    return str(self)

  def __str__(self):
    """Returns custom string to identify this patch."""
    s = '%s:%s' % (self.project, self.ref)
    if self.sha1 is not None:
      s = '%s:%s%s' % (s, site_config.params.CHANGE_PREFIX[self.remote],
                       self.sha1[:8])
    # TODO(ferringb,build): This gets a bit long in output; should likely
    # do some form of truncation to it.
    if self._subject_line:
      s += ' "%s"' % (self._subject_line,)
    return s

  def GetLocalSHA1(self, git_repo, revision):
    """Get the local SHA1 for this patch in the given |manifest|.

    Args:
      git_repo: The path to the repo.
      revision: The tracking branch.

    Returns:
      The local SHA1 for this patch, if it is present in the given |manifest|.
      If this patch is not present, returns None.
    """
    query = 'Change-Id: %s' % self.change_id
    cmd = ['log', '-F', '--all-match', '--grep', query,
           '--format=%H', '%s..HEAD' % revision]
    output = git.RunGit(git_repo, cmd).output.split()
    if len(output) == 1:
      return output[0]
    elif len(output) > 1:
      raise BrokenChangeID(self, 'Duplicate change ID')


class LocalPatch(GitRepoPatch):
  """Represents patch coming from an on-disk git repo."""

  def __init__(self, project_url, project, ref, tracking_branch, remote,
               sha1):
    GitRepoPatch.__init__(self, project_url, project, ref, tracking_branch,
                          remote, sha1=sha1)
    # Initialize our commit message/ChangeId now, since we know we have
    # access to the data right now.
    self.Fetch(project_url)

  def _GetCarbonCopy(self):
    """Returns a copy of this commit object, with a different sha1.

    This is used to work around a Gerrit bug, where a commit object cannot be
    uploaded for review if an existing branch (in refs/tryjobs/*) points to
    that same sha1.  So instead we create a copy of the commit object and upload
    that to refs/tryjobs/*.

    Returns:
      The sha1 of the new commit object.
    """
    hash_fields = [('tree_hash', '%T'), ('parent_hash', '%P')]
    transfer_fields = [('GIT_AUTHOR_NAME', '%an'),
                       ('GIT_AUTHOR_EMAIL', '%ae'),
                       ('GIT_AUTHOR_DATE', '%ad'),
                       ('GIT_COMMITTER_NAME', '%cn'),
                       ('GIT_COMMITTER_EMAIL', '%ce'),
                       ('GIT_COMMITER_DATE', '%ct')]
    fields = hash_fields + transfer_fields

    format_string = '%n'.join([code for _, code in fields] + ['%B'])
    result = git.RunGit(self.project_url,
                        ['log', '--format=%s' % format_string, '-n1',
                         self.sha1])
    lines = result.output.splitlines()
    field_value = dict(zip([name for name, _ in fields],
                           [line.strip() for line in lines]))
    commit_body = '\n'.join(lines[len(fields):])

    if len(field_value['parent_hash'].split()) != 1:
      raise PatchException(self,
                           'Branch %s:%s contains merge result %s!'
                           % (self.project, self.ref, self.sha1))

    extra_env = dict([(field, field_value[field]) for field, _ in
                      transfer_fields])

    # Reset the commit date to a value that can't conflict; if we
    # leave this to git, it's possible for a fast moving set of commit/uploads
    # to all occur within the same second (thus the same commit date),
    # resulting in the same sha1.
    extra_env['GIT_COMMITTER_DATE'] = str(
        int(extra_env['GIT_COMMITER_DATE']) - 1)

    result = git.RunGit(
        self.project_url,
        ['commit-tree', field_value['tree_hash'], '-p',
         field_value['parent_hash']],
        extra_env=extra_env, input=commit_body)

    new_sha1 = result.output.strip()
    if new_sha1 == self.sha1:
      raise PatchException(
          self,
          'Internal error!  Carbon copy of %s is the same as original!'
          % self.sha1)

    return new_sha1

  def Upload(self, push_url, remote_ref, carbon_copy=True, dryrun=False,
             reviewers=(), cc=()):
    """Upload the patch to a remote git branch.

    Args:
      push_url: Which url to push to.
      remote_ref: The ref on the remote host to push to.
      carbon_copy: Use a carbon_copy of the local commit.
      dryrun: Do the git push with --dry-run
      reviewers: Iterable of reviewers to add.
      cc: Iterable of people to add to cc.

    Returns:
      A list of gerrit URLs found in the output
    """
    if carbon_copy:
      ref_to_upload = self._GetCarbonCopy()
    else:
      ref_to_upload = self.sha1

    cmd = ['push']

    # This matches repo's project.py:Project.UploadForReview logic.
    if reviewers or cc:
      if push_url.startswith('ssh://'):
        rp = (['gerrit receive-pack'] +
              ['--reviewer=%s' % x for x in reviewers] +
              ['--cc=%s' % x for x in cc])
        cmd.append('--receive-pack=%s' % ' '.join(rp))
      else:
        rp = ['r=%s' % x for x in reviewers] + ['cc=%s' % x for x in cc]
        remote_ref += '%' + ','.join(rp)

    cmd += [push_url, '%s:%s' % (ref_to_upload, remote_ref)]
    if dryrun:
      cmd.append('--dry-run')

    # Depending on git/gerrit/weather, the URL might be written to stdout or
    # stderr.  Just combine them so we don't have to worry about it.
    result = git.RunGit(self.project_url, cmd, capture_output=True,
                        combine_stdout_stderr=True)
    lines = result.output.splitlines()
    urls = []
    for num, line in enumerate(lines):
      # Look for output like:
      # remote: New Changes:
      # remote:   https://chromium-review.googlesource.com/36756 Enforce a ...
      if 'New Changes:' in line:
        urls = []
        for line in lines[num + 1:]:
          line = line.split()
          if len(line) < 2 or not line[1].startswith('http'):
            break
          urls.append(line[1])
        break
    return urls


class UploadedLocalPatch(GitRepoPatch):
  """Represents an uploaded local patch passed in using --remote-patch."""

  def __init__(self, project_url, project, ref, tracking_branch,
               original_branch, original_sha1, remote, carbon_copy_sha1=None):
    """Initializes an UploadedLocalPatch instance.

    Args:
      project_url: See GitRepoPatch for documentation.
      project: See GitRepoPatch for documentation.
      ref: See GitRepoPatch for documentation.
      tracking_branch: See GitRepoPatch for documentation.
      original_branch: The tracking branch of the local patch.
      original_sha1: The sha1 of the local commit.
      remote: See GitRepoPatch for documentation.
      carbon_copy_sha1: The alternative commit hash to use.
    """
    GitRepoPatch.__init__(self, project_url, project, ref, tracking_branch,
                          remote, sha1=carbon_copy_sha1)
    self.original_branch = original_branch
    self.original_sha1 = ParseSHA1(original_sha1)
    self._original_sha1_valid = False if self.original_sha1 is None else True
    if self._original_sha1_valid and not self.id:
      self.id = AddPrefix(self, self.original_sha1)

  def LookupAliases(self):
    """Return the list of lookup keys this change is known by."""
    l = GitRepoPatch.LookupAliases(self)
    if self._original_sha1_valid:
      l.append(AddPrefix(self, self.original_sha1))

    return l

  def __str__(self):
    """Returns custom string to identify this patch."""
    s = '%s:%s:%s' % (self.project, self.original_branch,
                      self.original_sha1[:8])
    # TODO(ferringb,build): This gets a bit long in output; should likely
    # do some form of truncation to it.
    if self._subject_line:
      s += ':"%s"' % (self._subject_line,)
    return s


class GerritFetchOnlyPatch(GitRepoPatch):
  """Object that contains information to cherry-pick a Gerrit CL."""

  def __init__(self, project_url, project, ref, tracking_branch, remote,
               sha1, change_id, gerrit_number, patch_number, owner_email=None,
               fail_count=0, pass_count=0, total_fail_count=0,
               commit_message=None):
    """Initializes a GerritFetchOnlyPatch object."""
    super(GerritFetchOnlyPatch, self).__init__(
        project_url, project, ref, tracking_branch, remote,
        change_id=change_id, sha1=sha1)
    self.gerrit_number = gerrit_number
    self.patch_number = patch_number
    # TODO: Do we need three variables for the commit hash?
    self.revision = self.commit = self.sha1

    # Variables below are required to print the CL link.
    self.owner_email = owner_email
    self.owner = None
    if self.owner_email:
      self.owner = self.owner_email.split('@', 1)[0]

    self.url = gob_util.GetChangePageUrl(
        site_config.params.GERRIT_HOSTS[self.remote], int(self.gerrit_number))
    self.fail_count = fail_count
    self.pass_count = pass_count
    self.total_fail_count = total_fail_count
    # commit_message is herited from GitRepoPatch, only override it when passed
    # in value is not None.
    if commit_message:
      self.commit_message = commit_message

  @classmethod
  def FromAttrDict(cls, attr_dict):
    """Get a GerritFetchOnlyPatch instance from a dict.

    Args:
      attr_dict: A dictionary with the keys given in ALL_ATTRS.
    """
    return GerritFetchOnlyPatch(attr_dict[ATTR_PROJECT_URL],
                                attr_dict[ATTR_PROJECT],
                                attr_dict[ATTR_REF],
                                attr_dict[ATTR_BRANCH],
                                attr_dict[ATTR_REMOTE],
                                attr_dict[ATTR_COMMIT],
                                attr_dict[ATTR_CHANGE_ID],
                                attr_dict[ATTR_GERRIT_NUMBER],
                                attr_dict[ATTR_PATCH_NUMBER],
                                owner_email=attr_dict[ATTR_OWNER_EMAIL],
                                fail_count=int(attr_dict[ATTR_FAIL_COUNT]),
                                pass_count=int(attr_dict[ATTR_PASS_COUNT]),
                                total_fail_count=int(
                                    attr_dict[ATTR_TOTAL_FAIL_COUNT]),
                                commit_message=attr_dict.get(
                                    ATTR_COMMIT_MESSAGE))


  def _EnsureId(self, commit_message):
    """Ensure we have a usable Change-Id

    Validate what we received from gerrit against what the commit message
    states.
    """
    # GerritPatch instances get their Change-Id from gerrit
    # directly; for this to fail, there is an internal bug.
    assert self.id is not None

    # For GerritPatches, we still parse the ID- this is
    # primarily so we can throw an appropriate warning,
    # and also validate our parsing against gerrit's in
    # the process.
    try:
      parsed_id = self._ParseChangeId(commit_message)
      if parsed_id != self.change_id:
        raise AssertionError(
            'For Change-Id %s, sha %s, our parsing of the Change-Id did not '
            'match what gerrit told us.  This is an internal bug: either our '
            "parsing no longer matches gerrit's, or somehow this instance's "
            'stored change_id was invalidly modified.  Our parsing of the '
            'Change-Id yielded: %s'
            % (self.change_id, self.sha1, parsed_id))

    except BrokenChangeID:
      logging.warning(
          'Change %s, Change-Id %s, sha1 %s lacks a change-id in its commit '
          'message.  This can break the ability for any children to depend on '
          'this Change as a parent.  Please add the appropriate '
          'Change-Id into the commit message to resolve this.',
          self, self.change_id, self.sha1)

  def GetAttributeDict(self):
    """Get a dictionary of attribute used for manifest.

    Returns:
      A dictionary with the keys given in ALL_ATTRS.
    """
    attr_dict = {
        ATTR_REMOTE: self.remote,
        ATTR_GERRIT_NUMBER: self.gerrit_number,
        ATTR_PROJECT: self.project,
        ATTR_PROJECT_URL: self.project_url,
        ATTR_REF: self.ref,
        ATTR_BRANCH: self.tracking_branch,
        ATTR_CHANGE_ID: self.change_id,
        ATTR_COMMIT: self.commit,
        ATTR_PATCH_NUMBER: self.patch_number,
        ATTR_OWNER_EMAIL: self.owner_email,
        ATTR_FAIL_COUNT: str(self.fail_count),
        ATTR_PASS_COUNT: str(self.pass_count),
        ATTR_TOTAL_FAIL_COUNT: str(self.total_fail_count),
        ATTR_COMMIT_MESSAGE: self.commit_message,
    }

    return attr_dict

class GerritPatch(GerritFetchOnlyPatch):
  """Object that represents a Gerrit CL."""

  def __init__(self, patch_dict, remote, url_prefix):
    """Construct a GerritPatch object from Gerrit query results.

    Gerrit query JSON fields are documented at:
    http://gerrit-documentation.googlecode.com/svn/Documentation/2.2.1/json.html

    Args:
      patch_dict: A dictionary containing the parsed JSON gerrit query results.
      remote: The manifest remote the patched project uses.
      url_prefix: The project name will be appended to this to get the full
                  repository URL.
    """
    self.patch_dict = patch_dict
    self.url_prefix = url_prefix
    current_patch_set = patch_dict.get('currentPatchSet', {})
    # id - The CL's ChangeId
    # revision - The CL's SHA1 hash.
    # number - The CL's gerrit number.
    super(GerritPatch, self).__init__(
        os.path.join(url_prefix, patch_dict['project']),
        patch_dict['project'],
        current_patch_set.get('ref'),
        patch_dict['branch'],
        remote,
        current_patch_set.get('revision'),
        patch_dict['id'],
        ParseGerritNumber(str(patch_dict['number'])),
        current_patch_set.get('number'),
        owner_email=patch_dict['owner']['email'])

    prefix_str = site_config.params.CHANGE_PREFIX[self.remote]
    self.gerrit_number_str = '%s%s' % (prefix_str, self.gerrit_number)
    self.url = patch_dict['url']
    # status - Current state of this change.  Can be one of
    # ['NEW', 'SUBMITTED', 'MERGED', 'ABANDONED'].
    self.status = patch_dict['status']
    self._approvals = []
    if 'currentPatchSet' in self.patch_dict:
      self._approvals = self.patch_dict['currentPatchSet'].get('approvals', [])
    self.commit_timestamp = current_patch_set.get('date', 0)
    self.approval_timestamp = max(
        self.commit_timestamp,
        max(x['grantedOn'] for x in self._approvals) if self._approvals else 0)
    self._commit_message = None
    self.commit_message = patch_dict.get('commitMessage')

  @staticmethod
  def ConvertQueryResults(change, host):
    """Converts HTTP query results to the old SQL format.

    The HTTP interface to gerrit uses a different json schema from the old SQL
    interface.  This method converts data from the new schema to the old one,
    typically before passing it to the GerritPatch constructor.

    Old interface:
      http://gerrit-documentation.googlecode.com/svn/Documentation/2.6/json.html

    New interface:
      https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#json-entities
    """
    try:
      _convert_tm = lambda tm: calendar.timegm(
          time.strptime(tm.partition('.')[0], '%Y-%m-%d %H:%M:%S'))
      _convert_user = lambda u: {
          'name': u.get('name'),
          'email': u.get('email'),
          'username': u.get('name'),
      }
      change_id = change['change_id'].split('~')[-1]
      patch_dict = {
          'project': change['project'],
          'branch': change['branch'],
          'createdOn': _convert_tm(change['created']),
          'lastUpdated': _convert_tm(change['updated']),
          'id': change_id,
          'owner': _convert_user(change['owner']),
          'number': str(change['_number']),
          'url': gob_util.GetChangePageUrl(host, change['_number']),
          'status': change['status'],
          'subject': change.get('subject'),
      }
      current_revision = change.get('current_revision', '')
      current_revision_info = change.get('revisions', {}).get(current_revision)
      if current_revision_info:
        approvals = []
        for label, label_data in change['labels'].iteritems():
          # Skip unknown labels.
          if label not in constants.GERRIT_ON_BORG_LABELS:
            continue
          for review_data in label_data.get('all', []):
            granted_on = review_data.get('date', change['created'])
            approvals.append({
                'type': constants.GERRIT_ON_BORG_LABELS[label],
                'description': label,
                'value': str(review_data.get('value', '0')),
                'grantedOn': _convert_tm(granted_on),
                'by': _convert_user(review_data),
            })

        date = current_revision_info['commit']['committer']['date']
        patch_dict['currentPatchSet'] = {
            'approvals': approvals,
            'ref': current_revision_info['fetch']['http']['ref'],
            'revision': current_revision,
            'number': str(current_revision_info['_number']),
            'date': _convert_tm(date),
            'draft': current_revision_info.get('draft', False),
        }

        current_commit = current_revision_info.get('commit')
        if current_commit:
          patch_dict['commitMessage'] = current_commit['message']
          parents = current_commit.get('parents', [])
          patch_dict['dependsOn'] = [{'revision': p['commit']} for p in parents]

      return patch_dict
    except:
      logging.error('Error while converting:\n%s', change, exc_info=True)
      raise

  def __reduce__(self):
    """Used for pickling to re-create patch object."""
    return self.__class__, (self.patch_dict.copy(), self.remote,
                            self.url_prefix)

  def GerritDependencies(self):
    """Returns the list of PatchQuery objects that this patch depends on."""
    results = []
    for d in self.patch_dict.get('dependsOn', []):
      gerrit_number = d.get('number')
      if gerrit_number is not None:
        gerrit_number = ParseGerritNumber(gerrit_number, error_ok=False)

      change_id = d.get('id')
      if change_id is not None:
        change_id = ParseChangeID(change_id, error_ok=False)

      sha1 = d.get('revision')
      if sha1 is not None:
        sha1 = ParseSHA1(sha1, error_ok=False)

      if not gerrit_number and not change_id and not sha1:
        raise AssertionError(
            'While processing the dependencies of change %s, no "number", "id",'
            ' or "revision" key found in: %r' % (self.gerrit_number, d))

      results.append(
          PatchQuery(self.remote, project=self.project,
                     tracking_branch=self.tracking_branch,
                     gerrit_number=gerrit_number,
                     change_id=change_id, sha1=sha1))
    return results

  def IsAlreadyMerged(self):
    """Returns whether the patch has already been merged in Gerrit."""
    return self.status == 'MERGED'

  def IsBeingMerged(self):
    """Whether the patch is merged or in the progress of being merged."""
    return self.status in ('SUBMITTED', 'MERGED')

  def IsDraft(self):
    """Return true if the latest patchset is a draft."""
    return self.patch_dict['currentPatchSet']['draft']

  def HasApproval(self, field, value):
    """Return whether the current patchset has the specified approval.

    Args:
      field: Which field to check.
        'VRIF': Whether patch was verified.
        'CRVW': Whether patch was approved.
        'COMR': Whether patch was marked commit ready.
        'TRY':  Whether patch was marked ready for trybot.
      value: The expected value of the specified field (as string, or as list
             of accepted strings).
    """
    # All approvals default to '0', so use that if there's no matches.
    type_approvals = [x['value'] for x in self._approvals if x['type'] == field]
    type_approvals = type_approvals or ['0']
    if isinstance(value, (tuple, list)):
      return bool(set(value) & set(type_approvals))
    else:
      return value in type_approvals

  def HasApprovals(self, flags):
    """Return whether the current patchset has the specified approval.

    Args:
      flags: A dictionary of flag -> value mappings in
        GerritPatch.HasApproval format.
        ex: { 'CRVW': '2', 'VRIF': '1', 'COMR': ('1', '2') }

    returns boolean telling if all flag requirements are met.
    """
    return all(self.HasApproval(field, value)
               for field, value in flags.iteritems())

  def WasVetoed(self):
    """Return whether this CL was vetoed with VRIF=-1 or CRVW=-2."""
    return self.HasApproval('VRIF', '-1') or self.HasApproval('CRVW', '-2')

  def IsMergeable(self):
    """Return true if all Gerrit approvals required for submission are set."""
    return not self.GetMergeException()

  def HasReadyFlag(self):
    """Return true if the trybot-ready or commit-ready flag is set."""
    return self.HasApproval('COMR', ('1', '2')) or self.HasApproval('TRY', '1')

  def GetMergeException(self):
    """Return the reason why this change is not mergeable.

    If the change is in fact mergeable, return None.
    """
    if self.IsDraft():
      return PatchNotMergeable(self, 'is a draft.')

    if self.status != 'NEW':
      statuses = {
          'MERGED': 'is already merged.',
          'SUBMITTED': 'is being merged.',
          'ABANDONED': 'is abandoned.',
      }
      message = statuses.get(self.status, 'has status %s.' % self.status)
      return PatchNotMergeable(self, message)

    if self.HasApproval('VRIF', '-1'):
      return PatchNotMergeable(self, 'is marked as Verified=-1.')
    elif self.HasApproval('CRVW', '-2'):
      return PatchNotMergeable(self, 'is marked as Code-Review=-2.')
    elif not self.HasApproval('CRVW', '2'):
      return PatchNotMergeable(self, 'is not marked Code-Review=+2.')
    elif not self.HasApproval('VRIF', '1'):
      return PatchNotMergeable(self, 'is not marked Verified=+1.')
    elif not self.HasApproval('COMR', ('1', '2')):
      return PatchNotMergeable(self, 'is not marked Commit-Queue>=+1.')

  def GetLatestApproval(self, field):
    """Return most recent value of specific field on the current patchset.

    Args:
      field: Which field to check ('VRIF', 'CRVW', ...).

    Returns:
      Most recent field value (as str) or '0' if no such field.
    """
    # All approvals default to '0', so use that if there's no matches.
    type_approvals = [x['value'] for x in self._approvals if x['type'] == field]
    return type_approvals[-1] if type_approvals else '0'

  def PatchLink(self):
    """Return a CL link for this patch."""
    return 'CL:%s' % (self.gerrit_number_str,)

  def _AddFooters(self, msg):
    """Ensure that commit messages have necessary Gerrit footers on the end.

    Args:
      msg: The commit message.

    Returns:
      The modified commit message with necessary Gerrit footers.
    """
    msg = super(GerritPatch, self)._AddFooters(msg)

    # This function is adapted from the version in Gerrit:
    # goto/createCherryPickCommitMessage
    old_footers = self._GetFooters(msg)

    gerrit_host = site_config.params.GERRIT_HOSTS[self.remote]
    reviewed_on = 'https://%s/%s' % (gerrit_host, self.gerrit_number)
    if ('Reviewed-on', reviewed_on) not in old_footers:
      msg += 'Reviewed-on: %s\n' % reviewed_on

    for approval in self._approvals:
      footer = FooterForApproval(approval, old_footers)
      if footer and footer not in old_footers:
        msg += '%s: %s\n' % footer

    return msg

  def __str__(self):
    """Returns custom string to identify this patch."""
    s = '%s:%s' % (self.owner, self.gerrit_number_str)
    if self.sha1 is not None:
      s = '%s:%s%s' % (s, site_config.params.CHANGE_PREFIX[self.remote],
                       self.sha1[:8])
    if self._subject_line:
      s += ':"%s"' % (self._subject_line,)
    return s


FOOTER_TAGS_BY_APPROVAL_TYPE = {
    'CRVW': 'Reviewed-by',
    'VRIF': 'Tested-by',
    'COMR': 'Commit-Ready',
    'TRY': None,
    'SUBM': 'Submitted-by',
}


def FooterForApproval(approval, footers):
  """Return a commit-message footer for a given approver.

  Args:
    approval: A dict containing the information about an approver
    footers: A sequence of existing footers in the commit message.

  Returns:
    A 'footer', which is a tuple (tag, id).
  """
  if int(approval.get('value', 0)) <= 0:
    # Negative votes aren't counted.
    return

  name = approval.get('by', {}).get('name')
  email = approval.get('by', {}).get('email')
  ident = ' '.join(x for x in [name, email and '<%s>' % email] if x)

  # Nothing reasonable to describe them by? Ignore them.
  if not ident:
    return

  # Don't bother adding additional footers if the CL has already been
  # signed off.
  if ('Signed-off-by', ident) in footers:
    return

  # If the tag is unknown, don't return anything at all.
  if approval['type'] not in FOOTER_TAGS_BY_APPROVAL_TYPE:
    logging.warning('unknown gerrit type %s (%r)', approval['type'], approval)
    return

  # We don't care about certain gerrit flags as they aren't approval related.
  tag = FOOTER_TAGS_BY_APPROVAL_TYPE[approval['type']]
  if not tag:
    return

  return tag, ident


def GeneratePatchesFromRepo(git_repo, project, tracking_branch, branch, remote,
                            allow_empty=False):
  """Create a list of LocalPatch objects from a repo on disk.

  Args:
    git_repo: The path to the repo.
    project: The name of the associated project.
    tracking_branch: The remote tracking branch we want to test against.
    branch: The name of our local branch, where we will look for patches.
    remote: The name of the remote to use. E.g. 'cros'
    allow_empty: Whether to allow the case where no patches were specified.
  """

  result = git.RunGit(
      git_repo,
      ['rev-list', '--reverse', '%s..%s' % (tracking_branch, branch)])

  sha1s = result.output.splitlines()
  if not sha1s:
    if not allow_empty:
      cros_build_lib.Die('No changes found in %s:%s' % (project, branch))
    return

  for sha1 in sha1s:
    yield LocalPatch(os.path.join(git_repo, '.git'),
                     project, branch, tracking_branch,
                     remote, sha1)


def PrepareLocalPatches(manifest, patches):
  """Finish validation of parameters, and save patches to a temp folder.

  Args:
    manifest: The manifest object for the checkout in question.
    patches: A list of user-specified patches, in project:branch form.
      cbuildbot pre-processes the patch names before sending them to us,
      so we can expect that branch names will always be present.
  """
  patch_info = []
  for patch in patches:
    project, branch = patch.split(':')
    project_patch_info = []
    for checkout in manifest.FindCheckouts(project, only_patchable=True):
      tracking_branch = checkout['tracking_branch']
      project_dir = checkout.GetPath(absolute=True)
      remote = checkout['remote']
      project_patch_info.extend(GeneratePatchesFromRepo(
          project_dir, project, tracking_branch, branch, remote))

    if not project_patch_info:
      cros_build_lib.Die('No changes found in %s:%s' % (project, branch))
    patch_info.extend(project_patch_info)

  return patch_info


def PrepareRemotePatches(patches):
  """Generate patch objects from list of --remote-patch parameters.

  Args:
    patches: A list of --remote-patches strings that the user specified on
             the commandline.  Patch strings are colon-delimited.  Patches come
             in the format
             <project>:<original_branch>:<ref>:<tracking_branch>:<tag>.
             A description of each element:
             project: The manifest project name that the patch is for.
             original_branch: The name of the development branch that the local
                              patch came from.
             ref: The remote ref that points to the patch.
             tracking_branch: The upstream branch that the original_branch was
                              tracking.  Should be a manifest branch.
             tag: Denotes whether the project is an internal or external
                  project.
  """
  patch_info = []
  for patch in patches:
    try:
      project, original_branch, ref, tracking_branch, tag = patch.split(':')
    except ValueError as e:
      raise ValueError(
          'Unexpected tryjob format.  You may be running an '
          "older version of chromite.  Run 'repo sync "
          "chromiumos/chromite'.  Error was %s" % e)

    if tag not in constants.PATCH_TAGS:
      raise ValueError('Bad remote patch format.  Unknown tag %s' % tag)

    remote = site_config.params.EXTERNAL_REMOTE
    if tag == constants.INTERNAL_PATCH_TAG:
      remote = site_config.params.INTERNAL_REMOTE

    push_url = site_config.params.GIT_REMOTES[remote]
    patch_info.append(UploadedLocalPatch(os.path.join(push_url, project),
                                         project, ref, tracking_branch,
                                         original_branch,
                                         os.path.basename(ref), remote))

  return patch_info


def GetChangesAsString(changes, prefix='CL:', delimiter=' '):
  """Gets a human readable string listing |changes| in CL:1234 form.

  Args:
    changes: A list of GerritPatch objects.
    prefix: Prefix to use. Defaults to 'CL:'
    delimiter: Delimiter to use. Defaults to a space.
  """
  formatted_changes = ['%s%s' % (prefix, AddPrefix(x, x.gerrit_number))
                       for x in changes]
  return delimiter.join(sorted(formatted_changes))
