OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import logging |
| 6 |
| 7 from infra.libs.decorators import cached_property |
| 8 |
| 9 from infra.libs.git2.util import CalledProcessError |
| 10 from infra.libs.git2.util import INVALID |
| 11 from infra.libs.git2.data import CommitData |
| 12 |
| 13 |
| 14 LOGGER = logging.getLogger(__name__) |
| 15 |
| 16 |
| 17 class Commit(object): |
| 18 """Represents the identity of a commit in a git repo.""" |
| 19 |
| 20 def __init__(self, repo, hsh): |
| 21 """ |
| 22 @type repo: Repo |
| 23 """ |
| 24 assert CommitData.HASH_RE.match(hsh) |
| 25 self._repo = repo |
| 26 self._hsh = hsh |
| 27 |
| 28 # Comparison & Representation |
| 29 def __eq__(self, other): |
| 30 return (self is other) or ( |
| 31 isinstance(other, Commit) and ( |
| 32 self.hsh == other.hsh |
| 33 ) |
| 34 ) |
| 35 |
| 36 def __ne__(self, other): |
| 37 return not (self == other) |
| 38 |
| 39 def __repr__(self): |
| 40 return 'Commit({_repo!r}, {_hsh!r})'.format(**self.__dict__) |
| 41 |
| 42 # Accessors |
| 43 # pylint: disable=W0212 |
| 44 repo = property(lambda self: self._repo) |
| 45 hsh = property(lambda self: self._hsh) |
| 46 |
| 47 # Properties |
| 48 @cached_property |
| 49 def data(self): |
| 50 """Get a structured data representation of this commit.""" |
| 51 try: |
| 52 raw_data = self.repo.run('cat-file', 'commit', self.hsh) |
| 53 except CalledProcessError: |
| 54 return INVALID |
| 55 return CommitData.from_raw(raw_data) |
| 56 |
| 57 @cached_property |
| 58 def parent(self): |
| 59 """Get the corresponding parent Commit() for this Commit(), or None. |
| 60 |
| 61 If self has more than one parent, this raises an Exception. |
| 62 """ |
| 63 parents = self.data.parents |
| 64 if len(parents) > 1: |
| 65 LOGGER.error('Commit %r has more than one parent!', self.hsh) |
| 66 return INVALID |
| 67 return self.repo.get_commit(parents[0]) if parents else None |
| 68 |
| 69 # Methods |
| 70 def alter(self, **kwargs): |
| 71 """Get a new Commit which is the same as this one, except for alterations |
| 72 specified by kwargs. |
| 73 |
| 74 This will intern the new Commit object into the Repo. |
| 75 """ |
| 76 return self.repo.get_commit( |
| 77 self.repo.intern(self.data.alter(**kwargs), 'commit')) |
| 78 |
| 79 |
OLD | NEW |