# This file is part of maggit.
#
# Copyright 2015 Matthieu Gautier <dev@mgautier.fr>
#
# Pit is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pit is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# Additional permission under the GNU Affero GPL version 3 section 7:
#
# If you modify this Program, or any covered work, by linking or
# combining it with other code, such other code is not for that reason
# alone subject to any of the requirements of the GNU Affero GPL
# version 3.
#
# You should have received a copy of the GNU Affero General Public License
# along with maggit. If not, see http://www.gnu.org/licenses
#
# In summary:
# - You can use this program for no cost.
# - You can use this program for both personal and commercial reasons.
# - You do not have to share your own program's code which uses this program.
# - You have to share modifications (e.g bug-fixes, improvements) you've made to this program.
from .sha import Sha
from maggit import gitObjects
__all__ = ['Ref', 'Branche', 'Tag']
class BaseRef:
"""A Ref is a base class that represent a reference to a commit.
A ref can be (but not limited to) :
- a (remote) branche
- a tag
- a tag object
- a "static ref" (A ref object directly pointing to a object
"""
def __init__(self, repo):
self.repo = repo
def __getattr__(self, name):
try:
f = getattr(self, "_compute_"+name)
except KeyError:
raise KeyError("%s has not attribute %n"%(self, name))
v = f()
setattr(self, name, v)
return v
[docs]class Ref(BaseRef):
__slots__ = ('repo', 'sha', 'commit')
def __init__(self, repo, sha):
BaseRef.__init__(self, repo)
self.sha = sha
def _compute_commit(self):
return gitObjects.Commit(self.repo, self.sha)
[docs]class Branche(BaseRef):
__slots__ = ('repo', 'name', '_sha', '_object')
def __init__(self, repo, branchName):
BaseRef.__init__(self, repo)
self.name = branchName
self._sha = None
@property
def sha(self):
return Sha(self.repo.refs.get_ref_sha('heads/%s'%self.name))
@property
def commit(self):
sha = self.sha
if sha == self._sha:
try:
return self._object
except AttributeError:
pass
# No self._object or sha != self._sha:
self._sha = sha
self._object = gitObjects.Commit(self.repo, sha)
return self._object
[docs]class Tag(BaseRef):
__slots__ = ('repo',
'name',
'sha',
'object',
'commit')
def __init__(self, repo, tagName):
BaseRef.__init__(self, repo)
self.name = tagName
def _compute_sha(self):
return Sha(self.repo.refs.get_ref_sha('tags/%s'%self.name))
def _compute_object(self):
return self.repo.get_object(self.sha)
def _compute_commit(self):
commitSha = self.repo.refs.get_peel_ref_sha('tags/%s'%self.name)
if commitSha:
obj = self.repo.get_object(commitSha)
else:
obj = self.object
while type(obj) == gitObjects.Tag:
obj = obj.object
if type(obj) == gitObjects.Commit:
return obj
raise ValueError("Tag %s pointing to %s is not a pointing a commit"%(self.name, str(obj.sha)))