forked from deepfakes/faceswap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
git.py
157 lines (132 loc) · 4.69 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin python3
""" Handles command line calls to git """
import logging
import os
import sys
from subprocess import PIPE, Popen
logger = logging.getLogger(__name__)
class Git():
""" Handles calls to github """
def __init__(self) -> None:
logger.debug("Initializing: %s", self.__class__.__name__)
self._working_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
self._available = self._check_available()
logger.debug("Initialized: %s", self.__class__.__name__)
def _from_git(self, command: str) -> tuple[bool, list[str]]:
""" Execute a git command
Parameters
----------
command : str
The command to send to git
Returns
-------
success: bool
``True`` if the command succesfully executed otherwise ``False``
list[str]
The output lines from stdout if there was no error, otherwise from stderr
"""
logger.debug("command: '%s'", command)
cmd = f"git {command}"
with Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, cwd=self._working_dir) as proc:
stdout, stderr = proc.communicate()
retcode = proc.returncode
success = retcode == 0
lines = stdout.decode("utf-8", errors="replace").splitlines()
if not lines:
lines = stderr.decode("utf-8", errors="replace").splitlines()
logger.debug("command: '%s', returncode: %s, success: %s, lines: %s",
cmd, retcode, success, lines)
return success, lines
def _check_available(self) -> bool:
""" Check if git is available. Does a call to git status. If the process errors due to
folder ownership, attempts to add the folder to github safe folders list and tries
again
Returns
-------
bool
``True`` if git is available otherwise ``False``
"""
success, msg = self._from_git("status")
if success:
return True
config = next((line.strip() for line in msg if "add safe.directory" in line), None)
if not config:
return False
success, _ = self._from_git(config.split("git ", 1)[-1])
return True
@property
def status(self) -> list[str]:
""" Obtain the output of git status for tracked files only """
if not self._available:
return []
success, status = self._from_git("status -uno")
if not success or not status:
return []
return status
@property
def branch(self) -> str:
""" str: The git branch that is currently being used to execute Faceswap. """
status = next((line.strip() for line in self.status if "On branch" in line), "Not Found")
return status.replace("On branch ", "")
@property
def branches(self) -> list[str]:
""" list[str]: List of all available branches. """
if not self._available:
return []
success, branches = self._from_git("branch -a")
if not success or not branches:
return []
return branches
def update_remote(self) -> bool:
""" Update all branches to track remote
Returns
-------
bool
``True`` if update was succesful otherwise ``False``
"""
if not self._available:
return False
return self._from_git("remote update")[0]
def pull(self) -> bool:
""" Pull the current branch
Returns
-------
bool
``True`` if pull is successful otherwise ``False``
"""
if not self._available:
return False
return self._from_git("pull")[0]
def checkout(self, branch: str) -> bool:
""" Checkout the requested branch
Parameters
----------
branch : str
The branch to checkout
Returns
-------
bool
``True`` if the branch was succesfully checkout out otherwise ``False``
"""
if not self._available:
return False
return self._from_git(f"checkout {branch}")[0]
def get_commits(self, count: int) -> list[str]:
""" Obtain the last commits to the repo
Parameters
----------
count : int
The last number of commits to obtain
Returns
-------
list[str]
list of commits, or empty list if none found
"""
if not self._available:
return []
success, commits = self._from_git(f"log --pretty=oneline --abbrev-commit -n {count}")
if not success or not commits:
return []
return commits
git = Git()
""" :class:`Git`: Handles calls to github """