Skip to content

Commit 039bfe3

Browse files
committed
whoops forgot cmd.
1 parent d562517 commit 039bfe3

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed

lib/git/cmd.py

+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
import os
2+
import subprocess
3+
import re
4+
from utils import *
5+
from method_missing import MethodMissingMixin
6+
from errors import GitCommandError
7+
8+
# Enables debugging of GitPython's git commands
9+
GIT_PYTHON_TRACE = os.environ.get("GIT_PYTHON_TRACE", False)
10+
11+
class Git(MethodMissingMixin):
12+
"""
13+
The Git class manages communication with the Git binary
14+
"""
15+
def __init__(self, git_dir=None):
16+
super(Git, self).__init__()
17+
if git_dir:
18+
self.find_git_dir(git_dir)
19+
else:
20+
self.find_git_dir(os.getcwd())
21+
22+
def find_git_dir(self, path):
23+
"""Find the best value for self.git_dir.
24+
For bare repositories, this is the path to the bare repository.
25+
For repositories with work trees, this is the work tree path.
26+
27+
When barerepo.git is passed in, self.git_dir = barerepo.git
28+
When worktree/.git is passed in, self.git_dir = worktree
29+
When worktree is passed in, self.git_dir = worktree
30+
"""
31+
32+
path = os.path.abspath(path)
33+
self.git_dir = path
34+
35+
cdup = self.execute(["git", "rev-parse", "--show-cdup"])
36+
if cdup:
37+
path = os.path.abspath(os.path.join(self.git_dir, cdup))
38+
else:
39+
is_bare_repository =\
40+
self.rev_parse(is_bare_repository=True) == "true"
41+
is_inside_git_dir =\
42+
self.rev_parse(is_inside_git_dir=True) == "true"
43+
44+
if not is_bare_repository and is_inside_git_dir:
45+
path = os.path.dirname(self.git_dir)
46+
47+
self.git_dir = path
48+
49+
@property
50+
def get_dir(self):
51+
return self.git_dir
52+
53+
def execute(self, command,
54+
istream = None,
55+
with_status = False,
56+
with_stderr = False,
57+
with_exceptions = False,
58+
with_raw_output = False,
59+
):
60+
"""
61+
Handles executing the command on the shell and consumes and returns
62+
the returned information (stdout)
63+
64+
``command``
65+
The command argument list to execute
66+
67+
``istream``
68+
Standard input filehandle passed to subprocess.Popen.
69+
70+
``with_status``
71+
Whether to return a (status, str) tuple.
72+
73+
``with_stderr``
74+
Whether to combine stderr into the output.
75+
76+
``with_exceptions``
77+
Whether to raise an exception when git returns a non-zero status.
78+
79+
``with_raw_output``
80+
Whether to avoid stripping off trailing whitespace.
81+
82+
Returns
83+
str(output) # with_status = False (Default)
84+
tuple(int(status), str(output)) # with_status = True
85+
"""
86+
87+
if GIT_PYTHON_TRACE:
88+
print command
89+
90+
# Allow stderr to be merged into stdout when with_stderr is True.
91+
# Otherwise, throw stderr away.
92+
if with_stderr:
93+
stderr = subprocess.STDOUT
94+
else:
95+
stderr = subprocess.PIPE
96+
97+
# Start the process
98+
proc = subprocess.Popen(command,
99+
cwd = self.git_dir,
100+
stdin = istream,
101+
stderr = stderr,
102+
stdout = subprocess.PIPE
103+
)
104+
105+
# Wait for the process to return
106+
stdout_value, err = proc.communicate()
107+
proc.stdout.close()
108+
if proc.stderr:
109+
proc.stderr.close()
110+
111+
# Strip off trailing whitespace by default
112+
if not with_raw_output:
113+
stdout_value = stdout_value.rstrip()
114+
115+
# Grab the exit status
116+
status = proc.poll()
117+
if with_exceptions and status != 0:
118+
raise GitCommandError("%s returned exit status %d"
119+
% (str(command), status))
120+
121+
# Allow access to the command's status code
122+
if with_status:
123+
return (status, stdout_value)
124+
else:
125+
return stdout_value
126+
127+
def transform_kwargs(self, **kwargs):
128+
"""
129+
Transforms Python style kwargs into git command line options.
130+
"""
131+
args = []
132+
for k, v in kwargs.items():
133+
if len(k) == 1:
134+
if v is True:
135+
args.append("-%s" % k)
136+
else:
137+
args.append("-%s%s" % (k, v))
138+
else:
139+
if v is True:
140+
args.append("--%s" % dashify(k))
141+
else:
142+
args.append("--%s=%s" % (dashify(k), v))
143+
return args
144+
145+
def method_missing(self, method, *args, **kwargs):
146+
"""
147+
Run the given git command with the specified arguments and return
148+
the result as a String
149+
150+
``method``
151+
is the command
152+
153+
``args``
154+
is the list of arguments
155+
156+
``kwargs``
157+
is a dict of keyword arguments.
158+
This function accepts the same optional keyword arguments
159+
as execute().
160+
161+
Examples
162+
git.rev_list('master', max_count=10, header=True)
163+
164+
Returns
165+
Same as execute()
166+
"""
167+
168+
# Handle optional arguments prior to calling transform_kwargs
169+
# otherwise these'll end up in args, which is bad.
170+
istream = kwargs.pop("istream", None)
171+
with_status = kwargs.pop("with_status", None)
172+
with_stderr = kwargs.pop("with_stderr", None)
173+
with_exceptions = kwargs.pop("with_exceptions", None)
174+
with_raw_output = kwargs.pop("with_raw_output", None)
175+
176+
# Prepare the argument list
177+
opt_args = self.transform_kwargs(**kwargs)
178+
ext_args = map(str, args)
179+
args = opt_args + ext_args
180+
181+
call = ["git", dashify(method)]
182+
call.extend(args)
183+
184+
return self.execute(call,
185+
istream = istream,
186+
with_status = with_status,
187+
with_stderr = with_stderr,
188+
with_exceptions = with_exceptions,
189+
with_raw_output = with_raw_output,
190+
)

0 commit comments

Comments
 (0)