# Copyright (C) 2018 Avatao.com Innovative Learning Kft. # All Rights Reserved. See LICENSE file for details. from subprocess import run from getpass import getuser class SnapshotProvider: def __init__(self, directory, git_dir): author = f'{getuser()} via TFW {self.__class__.__name__}' self.gitenv = { 'GIT_DIR': git_dir, 'GIT_WORK_TREE': directory, 'GIT_AUTHOR_NAME': author, 'GIT_AUTHOR_EMAIL': '', 'GIT_COMMITTER_NAME': author, 'GIT_COMMITTER_EMAIL': '' } self._head_detached = False self._branch = 'master' self._branches = [self._branch] self._init_repo() def _init_repo(self): self._run(('git', 'init')) def take_snapshot(self): if self._head_detached: self._checkout_branch_from_head() self._run(('git', 'add', '-A')) self._run(('git', 'commit', '-m', 'Snapshot')) def _checkout_branch_from_head(self): head_hash = self._get_head_hash() self._run(( 'git', 'checkout', '-b', head_hash, head_hash )) self._branches.append(head_hash) self._branch = head_hash self._head_detached = False def _get_head_hash(self): return self._get_stdout(('git', 'rev-parse', 'HEAD')) def restore_snapshot(self, date): commit = self._get_commit_from_timestamp(date) self._checkout_commit(commit) self._head_detached = True def _get_commit_from_timestamp(self, date): return self._get_stdout(( 'git', 'rev-list', '--date=iso', '-n', '1', f'--before="{date.isoformat()}"', self._branch )) def _checkout_commit(self, commit): self._run(( 'git', 'checkout', commit )) def _get_stdout(self, *args, **kwargs): kwargs['capture_output'] = True stdout_bytes = self._run(*args, **kwargs).stdout return stdout_bytes.decode().rstrip('\n') def _run(self, *args, **kwargs): if 'env' not in kwargs: kwargs['env'] = self.gitenv return run(*args, **kwargs)