wily\archivers\git.py
-- -- --- --- --- --- --- --- ------- ------- ------- | """
-- -- --- --- --- --- --- --- ------- ------- ------- | Git Archiver.
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- | Implementation of the archiver API for the gitpython module.
-- -- --- --- --- --- --- --- ------- ------- ------- | """
-- -- --- --- --- --- --- --- ------- ------- ------- | import logging
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- | from git import Repo
-- -- --- --- --- --- --- --- ------- ------- ------- | import git.exc
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- | from wily.archivers import BaseArchiver, Revision
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- | logger = logging.getLogger(__name__)
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
01 -- --- --- --- --- --- --- ------- ------- ------- | class InvalidGitRepositoryError(Exception):
01 -- --- --- --- --- --- --- ------- ------- ------- | """Error for when a folder is not a git repo."""
01 -- --- --- --- --- --- --- ------- ------- ------- |
01 -- --- --- --- --- --- --- ------- ------- ------- | pass
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
02 -- --- --- --- --- --- --- ------- ------- ------- | class DirtyGitRepositoryError(Exception):
02 -- --- --- --- --- --- --- ------- ------- ------- | """Error for a dirty git repository (untracked files)."""
02 -- --- --- --- --- --- --- ------- ------- ------- |
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | def __init__(self, untracked_files):
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | Raise error for untracked files.
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :param untracked_files: List of untracked files
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :param untracked_files: ``list``
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | self.untracked_files = untracked_files
02 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | self.message = "Dirty repository, make sure you commit/stash files first"
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
03 -- --- --- --- --- --- --- ------- ------- ------- | class GitArchiver(BaseArchiver):
03 -- --- --- --- --- --- --- ------- ------- ------- | """Gitpython implementation of the base archiver."""
03 -- --- --- --- --- --- --- ------- ------- ------- |
03 -- --- --- --- --- --- --- ------- ------- ------- | name = "git"
03 -- --- --- --- --- --- --- ------- ------- ------- |
03 02 001 001 001 001 002 002 0002.00 0001.00 0000.50 | def __init__(self, config):
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | """
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | Instantiate a new Git Archiver.
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 |
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | :param config: The wily configuration
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | :type config: :class:`wily.config.WilyConfig`
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | """
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | try:
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | self.repo = Repo(config.path)
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | except git.exc.InvalidGitRepositoryError as e:
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | raise InvalidGitRepositoryError from e
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 |
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | self.config = config
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | self.current_branch = self.repo.active_branch
03 -- 001 001 001 001 002 002 0002.00 0001.00 0000.50 | assert not self.repo.bare, "Not a Git repository"
03 -- --- --- --- --- --- --- ------- ------- ------- |
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | def revisions(self, path, max_revisions):
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | Get the list of revisions.
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :param path: the path to target.
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :type path: ``str``
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :param max_revisions: the maximum number of revisions.
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :type max_revisions: ``int``
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :return: A list of revisions.
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :rtype: ``list`` of :class:`Revision`
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | if self.repo.is_dirty():
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | raise DirtyGitRepositoryError(self.repo.untracked_files)
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | revisions = []
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | for commit in self.repo.iter_commits(
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | self.current_branch, max_count=max_revisions
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | ):
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | rev = Revision(
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | key=commit.name_rev.split(" ")[0],
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | author_name=commit.author.name,
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | author_email=commit.author.email,
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | date=commit.committed_date,
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | message=commit.message,
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | files=list(commit.stats.files.keys()),
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | )
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | revisions.append(rev)
03 03 000 000 000 000 000 000 0000.00 0000.00 0000.00 | return revisions
03 -- --- --- --- --- --- --- ------- ------- ------- |
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | def checkout(self, revision, options):
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | Checkout a specific revision.
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :param revision: The revision identifier.
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :type revision: :class:`Revision`
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :param options: Any additional options.
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | :type options: ``dict``
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | rev = revision.key
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | self.repo.git.checkout(rev)
03 -- --- --- --- --- --- --- ------- ------- ------- |
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | def finish(self):
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | Clean up any state if processing completed/failed.
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | For git, will checkout HEAD on the original branch when finishing
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | """
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | self.repo.git.checkout(self.current_branch)
03 01 000 000 000 000 000 000 0000.00 0000.00 0000.00 | self.repo.close()