-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit_commands.py
132 lines (106 loc) · 3.5 KB
/
git_commands.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
import bash
from gc_exceptions import GcException, MergeFailure
import re
import os
import os.path
import shutil
FETCH = "fetch"
PULL = "pull origin %s"
PUSH = "push origin %s"
CHECKOUT = "checkout %s"
MERGE = "merge %s"
STATUS = "status"
TREE = "--no-pager log --oneline --abbrev-commit --all --graph --decorate"
RESET = "reset --hard"
CLEAN = "clean -f"
DELETE_BRANCH_REMOTE = "push origin --delete %s"
DELETE_BRANCH_LOCAL = "branch -D %s"
ADD_REMOTE = "remote add origin %s"
def _get(command):
return bash.execute_inner(command)["stdout"]
def _merge_step(command):
bash.execute(command, MergeFailure)
def _general_action(command):
bash.execute(command, GcException)
def _stderr(command):
rv = bash.execute_inner(command)
if rv["rc"] == 0:
return ""
else:
return rv["stderr"]
class Repository(object):
def __init__(self, path, master):
self.prefix = "git -C %s " % path
self.master = master
self.path = path
self._remote = None
self._remote_problems = None
self.branch = None
@property
def remote(self):
if not self._remote:
self._remote = self._load_remote()
return self._remote
@remote.setter
def remote(self, remote):
print("setting remote to: %s" % remote)
active_repo = self.path
backup_repo = active_repo + ".backup"
shutil.move(active_repo, backup_repo)
try:
os.mkdir(active_repo)
self.init(remote)
except:
shutil.move(backup_repo, active_repo)
raise
shutil.rmtree(backup_repo)
self._remote = remote
self._remote_problems = None
def remote_problems(self):
if self._remote_problems == None:
self._remote_problems = self._execute("ls-remote", _stderr)
return self._remote_problems
def init(self, remote):
self._execute("init", _general_action)
self._execute(ADD_REMOTE % remote, _general_action)
def checkout(self, branch):
if self.branch != branch:
self._execute(CHECKOUT % branch)
self.branch = branch
def fetch(self):
self._execute(FETCH)
self.checkout(self.master)
self._execute(MERGE % "origin/"+self.master)
def merge_and_push(self, branch):
self.merge(self.master, branch)
self.push()
def merge(self, target_branch, source_branch):
self.checkout(target_branch)
self._execute(MERGE % source_branch)
def push(self):
self.checkout(self.master)
self._execute(PUSH % self.master)
def delete_remote_branch(self, branch):
self.checkout(self.master)
self._execute(DELETE_BRANCH_REMOTE % branch)
def delete_local_branch(self, branch):
self.checkout(self.master)
self._execute(DELETE_BRANCH_LOCAL % branch)
def clean(self):
self._execute(RESET)
self._execute(CLEAN)
def status(self):
return self._execute(STATUS, _get)
def tree(self):
return self._execute(TREE, _get)
def _execute(self, command, execute_inner=_merge_step):
return execute_inner(self.prefix + command)
def _load_remote(self):
config_file = "%s/.git/config" % self.path
if os.path.isfile(config_file):
with open(config_file, "r") as f:
content = f.read()
m = re.search("\[remote \"origin\"\][^\[]*url = ([^\n]+)", content)
if m:
return m.group(1)
return ""