89 lines
2.8 KiB
Python
89 lines
2.8 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2014, Craig Tracey <craigtracey@gmail.com>
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
|
|
import datetime
|
|
import logging
|
|
import re
|
|
import time
|
|
|
|
from git import Repo
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class OpenstackGitRepo(object):
|
|
def __init__(self, url, ref='master'):
|
|
self.url = url
|
|
self.ref = ref
|
|
self._repo = None
|
|
self._head = None
|
|
self._change_id = None
|
|
self._committed_date = None
|
|
|
|
@property
|
|
def cloned(self):
|
|
return self._repo is not None
|
|
|
|
@property
|
|
def head(self):
|
|
if not self._head and self._repo:
|
|
self._head = self._repo.head.commit.hexsha
|
|
return self._head
|
|
|
|
@property
|
|
def change_id(self):
|
|
if not self._change_id and self._repo:
|
|
for commit in self._repo.iter_commits():
|
|
match = re.search('Change-Id:\s*(I\w+)', commit.message)
|
|
if match:
|
|
self._change_id = match.group(1)
|
|
break
|
|
return self._change_id
|
|
|
|
@property
|
|
def committed_date(self):
|
|
if not self._committed_date and self._repo:
|
|
self._committed_date = self._repo.head.commit.committed_date
|
|
return self._committed_date
|
|
|
|
def _invalidate_attrs(self):
|
|
self._head = None
|
|
self._change_id = None
|
|
self._committed_date = None
|
|
|
|
def clone(self, outdir):
|
|
LOG.info("Cloning '%s' to '%s'", self.url, outdir)
|
|
self._repo = Repo.clone_from(self.url, outdir)
|
|
git = self._repo.git
|
|
git.checkout(self.ref)
|
|
self._invalidate_attrs()
|
|
|
|
def reset_to_date(self, date):
|
|
if self._repo:
|
|
commit_date_sha = None
|
|
for commit in self._repo.iter_commits():
|
|
if commit.committed_date >= date:
|
|
commit_date_sha = commit.hexsha
|
|
elif commit.committed_date < date:
|
|
break
|
|
if not commit_date_sha:
|
|
raise Exception("Unable to find commit for date %s",
|
|
datetime.datetime.fromtimestamp(date))
|
|
git = self._repo.git
|
|
LOG.info("Reset repo '%s' to commit at '%s'", self.url,
|
|
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(date)))
|
|
git.checkout(commit_date_sha)
|