forked from scp-fs2open/nightlybuild
-
Notifications
You must be signed in to change notification settings - Fork 0
/
git.py
102 lines (76 loc) · 3.83 KB
/
git.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import os
import subprocess
import sys
class GitRepository:
def __init__(self, path, branch):
self.branch = branch
self.path = path
def _format_git_cmd(self, cmd):
return "git --git-dir='{}' --work-tree='{}' {}".format(os.path.join(self.path, ".git"), self.path, cmd)
def _git_get_output(self, cmd):
return subprocess.check_output(self._format_git_cmd(cmd), shell=True).strip().decode("UTF-8")
def _git_redirected(self, cmd):
print(">> git " + cmd)
return subprocess.call(self._format_git_cmd(cmd), shell=True, stdout=sys.stdout, stderr=sys.stderr,
stdin=sys.stdin)
def _git_redirected_success(self, cmd):
ret = self._git_redirected(cmd)
assert ret == 0
def get_commit(self):
return self._git_get_output("rev-parse --short {}".format(self.branch)).lower()
def get_log(self, pattern, tag_name):
tags = self._git_get_output("for-each-ref --sort=-taggerdate --format '%(tag)' refs/tags | grep '{}' | grep -A 1 {}"
.format(pattern, tag_name)).splitlines()
if len(tags) < 2:
return "No log available"
return self._git_get_output("log {}^..{}^ --no-merges --stat"
" --pretty=format:"
"\"------------------------------------------------------------------------%n"
"commit %h%nAuthor: %an <%ad>%n"
"Commit: %cn <%cd>%n%n %s\"".format(tags[1], tags[0]))
def get_latest_tag_name(self, pattern) -> str:
"""
@brief Retrieves the name of the most recent version tag commit.
"""
return self._git_get_output("for-each-ref --sort=-taggerdate --format '%(tag)' refs/tags | grep '{}' | head -n1"
.format(pattern))
def get_latest_tag_commit(self, pattern):
"""
@brief Retrieves the SHA of the most recent version tag commit.
"""
tag = self.get_latest_tag_name(pattern)
if len(tag) < 1:
return ""
return self._git_get_output("rev-parse --short {}^".format(tag))
def update_repository(self):
"""
@brief Updates the local repo to the most recent commit and deletes any untracked changes
"""
self._git_redirected_success("checkout '{}'".format(self.branch))
self._git_redirected_success("fetch --tags origin".format(self.branch))
self._git_redirected_success("reset --hard 'origin/{}'".format(self.branch))
def prepare_repo(self):
self._git_redirected_success("checkout '{}'".format(self.branch))
has_changes = self._git_redirected("diff-index --quiet HEAD --") != 0
stashed_changes = False
if has_changes:
print("Stashing local changes for later recovery")
self._git_redirected_success("stash -u -a")
stashed_changes = True
# Detach HEAD so we don't change the branch we are on
self._git_redirected_success("checkout --detach")
return stashed_changes
def commit_and_tag(self, tag_name):
"""
@brief Commit, tag (annotated), and push to origin/repo
"""
self._git_redirected_success("add .")
self._git_redirected_success(
"commit -m 'Automated build commit' --author='SirKnightly <[email protected]>'")
self._git_redirected_success("tag -a '{}' -m 'Build script tag'".format(tag_name))
self._git_redirected_success("push --tags")
def restore_repo(self, stashed_changes):
self._git_redirected_success("checkout '{}'".format(self.branch))
if stashed_changes:
print("Restoring previous changes")
self._git_redirected_success("stash pop")