| Index: infra/libs/git2/commit.py
|
| diff --git a/infra/libs/git2/commit.py b/infra/libs/git2/commit.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..410f67746f4debbc758c7e0e5f27c6a077bd7073
|
| --- /dev/null
|
| +++ b/infra/libs/git2/commit.py
|
| @@ -0,0 +1,79 @@
|
| +# Copyright 2014 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.
|
| +
|
| +import logging
|
| +
|
| +from infra.libs.decorators import cached_property
|
| +
|
| +from infra.libs.git2.util import CalledProcessError
|
| +from infra.libs.git2.util import INVALID
|
| +from infra.libs.git2.data import CommitData
|
| +
|
| +
|
| +LOGGER = logging.getLogger(__name__)
|
| +
|
| +
|
| +class Commit(object):
|
| + """Represents the identity of a commit in a git repo."""
|
| +
|
| + def __init__(self, repo, hsh):
|
| + """
|
| + @type repo: Repo
|
| + """
|
| + assert CommitData.HASH_RE.match(hsh)
|
| + self._repo = repo
|
| + self._hsh = hsh
|
| +
|
| + # Comparison & Representation
|
| + def __eq__(self, other):
|
| + return (self is other) or (
|
| + isinstance(other, Commit) and (
|
| + self.hsh == other.hsh
|
| + )
|
| + )
|
| +
|
| + def __ne__(self, other):
|
| + return not (self == other)
|
| +
|
| + def __repr__(self):
|
| + return 'Commit({_repo!r}, {_hsh!r})'.format(**self.__dict__)
|
| +
|
| + # Accessors
|
| + # pylint: disable=W0212
|
| + repo = property(lambda self: self._repo)
|
| + hsh = property(lambda self: self._hsh)
|
| +
|
| + # Properties
|
| + @cached_property
|
| + def data(self):
|
| + """Get a structured data representation of this commit."""
|
| + try:
|
| + raw_data = self.repo.run('cat-file', 'commit', self.hsh)
|
| + except CalledProcessError:
|
| + return INVALID
|
| + return CommitData.from_raw(raw_data)
|
| +
|
| + @cached_property
|
| + def parent(self):
|
| + """Get the corresponding parent Commit() for this Commit(), or None.
|
| +
|
| + If self has more than one parent, this raises an Exception.
|
| + """
|
| + parents = self.data.parents
|
| + if len(parents) > 1:
|
| + LOGGER.error('Commit %r has more than one parent!', self.hsh)
|
| + return INVALID
|
| + return self.repo.get_commit(parents[0]) if parents else None
|
| +
|
| + # Methods
|
| + def alter(self, **kwargs):
|
| + """Get a new Commit which is the same as this one, except for alterations
|
| + specified by kwargs.
|
| +
|
| + This will intern the new Commit object into the Repo.
|
| + """
|
| + return self.repo.get_commit(
|
| + self.repo.intern(self.data.alter(**kwargs), 'commit'))
|
| +
|
| +
|
|
|