blob: ae85d276637fd61920dc9ecc34f8939dc9a89d9d [file] [log] [blame]
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001#
2# Copyright (C) 2016 Intel Corporation
3#
4# Released under the MIT license (see COPYING.MIT)
5#
6"""Git repository interactions"""
7import os
8
9from oeqa.utils.commands import runCmd
10
11
12class GitError(Exception):
13 """Git error handling"""
14 pass
15
16class GitRepo(object):
17 """Class representing a Git repository clone"""
18 def __init__(self, path, is_topdir=False):
19 self.top_dir = self._run_git_cmd_at(['rev-parse', '--show-toplevel'],
20 path)
21 realpath = os.path.realpath(path)
22 if is_topdir and realpath != self.top_dir:
23 raise GitError("{} is not a Git top directory".format(realpath))
24
25 @staticmethod
26 def _run_git_cmd_at(git_args, cwd, **kwargs):
27 """Run git command at a specified directory"""
28 git_cmd = 'git ' if isinstance(git_args, str) else ['git']
29 git_cmd += git_args
30 ret = runCmd(git_cmd, ignore_status=True, cwd=cwd, **kwargs)
31 if ret.status:
32 cmd_str = git_cmd if isinstance(git_cmd, str) \
33 else ' '.join(git_cmd)
34 raise GitError("'{}' failed with exit code {}: {}".format(
35 cmd_str, ret.status, ret.output))
36 return ret.output.strip()
37
38 @staticmethod
39 def init(path):
40 """Initialize a new Git repository"""
41 GitRepo._run_git_cmd_at('init', cwd=path)
42 return GitRepo(path, is_topdir=True)
43
44 def run_cmd(self, git_args, env_update=None):
45 """Run Git command"""
46 env = None
47 if env_update:
48 env = os.environ.copy()
49 env.update(env_update)
50 return self._run_git_cmd_at(git_args, self.top_dir, env=env)
51
52 def rev_parse(self, revision):
53 """Do git rev-parse"""
54 try:
55 return self.run_cmd(['rev-parse', revision])
56 except GitError:
57 # Revision does not exist
58 return None
59
60 def get_current_branch(self):
61 """Get current branch"""
62 try:
63 # Strip 11 chars, i.e. 'refs/heads' from the beginning
64 return self.run_cmd(['symbolic-ref', 'HEAD'])[11:]
65 except GitError:
66 return None
67
68