1# ex:ts=4:sw=4:sts=4:et 2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- 3# 4# patchtestrepo: PatchTestRepo class used mainly to control a git repo from patchtest 5# 6# Copyright (C) 2016 Intel Corporation 7# 8# SPDX-License-Identifier: GPL-2.0-only 9# 10 11import git 12import os 13import mbox 14 15class PatchTestRepo(object): 16 17 # prefixes used for temporal branches/stashes 18 prefix = 'patchtest' 19 20 def __init__(self, patch, repodir, commit=None, branch=None): 21 self.repodir = repodir 22 self.repo = git.Repo.init(repodir) 23 self.patch = mbox.PatchSeries(patch) 24 self.current_branch = self.repo.active_branch.name 25 26 # targeted branch defined on the patch may be invalid, so make sure there 27 # is a corresponding remote branch 28 valid_patch_branch = None 29 if self.patch.branch in self.repo.branches: 30 valid_patch_branch = self.patch.branch 31 32 # Target Commit 33 # Priority (top has highest priority): 34 # 1. commit given at cmd line 35 # 2. branch given at cmd line 36 # 3. branch given at the patch 37 # 3. current HEAD 38 self._commit = self._get_commitid(commit) or \ 39 self._get_commitid(branch) or \ 40 self._get_commitid(valid_patch_branch) or \ 41 self._get_commitid('HEAD') 42 43 self._workingbranch = "%s_%s" % (PatchTestRepo.prefix, os.getpid()) 44 45 # create working branch. Use the '-B' flag so that we just 46 # check out the existing one if it's there 47 self.repo.git.execute(['git', 'checkout', '-B', self._workingbranch, self._commit]) 48 49 self._patchmerged = False 50 51 # Check if patch can be merged using git-am 52 self._patchcanbemerged = True 53 try: 54 # Make sure to get the absolute path of the file 55 self.repo.git.execute(['git', 'apply', '--check', os.path.abspath(self.patch.path)], with_exceptions=True) 56 except git.exc.GitCommandError as ce: 57 self._patchcanbemerged = False 58 59 def ismerged(self): 60 return self._patchmerged 61 62 def canbemerged(self): 63 return self._patchcanbemerged 64 65 def _get_commitid(self, commit): 66 67 if not commit: 68 return None 69 70 try: 71 return self.repo.rev_parse(commit).hexsha 72 except Exception as e: 73 print(f"Couldn't find commit {commit} in repo") 74 75 return None 76 77 def merge(self): 78 if self._patchcanbemerged: 79 self.repo.git.execute(['git', 'am', '--keep-cr', os.path.abspath(self.patch.path)]) 80 self._patchmerged = True 81 82 def clean(self): 83 self.repo.git.execute(['git', 'checkout', self.current_branch]) 84 self.repo.git.execute(['git', 'branch', '-D', self._workingbranch]) 85 self._patchmerged = False 86