Skip to content

Commit feed81e

Browse files
committed
Moved setup function into top level __init__
Discovered that the remote module also relies on the git executable as such it also needs to be “refreshed” anytime the git executable is updated or changed. This was best solved by moving the setup function into the top level __init__ where the setup simply calls git.cmd.Git.refresh and git.remote.FetchInfo.refresh.
1 parent a962464 commit feed81e

File tree

3 files changed

+67
-44
lines changed

3 files changed

+67
-44
lines changed

‎git/__init__.py

+17
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,20 @@ def _init_externals():
5757

5858
__all__ = [name for name, obj in locals().items()
5959
if not (name.startswith('_') or inspect.ismodule(obj))]
60+
61+
#{ Initialize git executable path
62+
def setup(path=None):
63+
"""Convenience method for setting the git executable path."""
64+
if not Git.refresh(path=path):
65+
return
66+
if not FetchInfo.refresh():
67+
return
68+
69+
def refresh(path=None):
70+
"""Convenience method for refreshing the git executable path."""
71+
setup(path=path)
72+
#} END initialize git executable path
73+
74+
#################
75+
setup()
76+
#################

‎git/cmd.py

+20-34
Original file line numberDiff line numberDiff line change
@@ -190,61 +190,60 @@ def __setstate__(self, d):
190190
USE_SHELL = False
191191

192192
# Provide the full path to the git executable. Otherwise it assumes git is in the path
193-
@classmethod
194-
def refresh(cls, path=None):
195-
"""Convenience method for refreshing the git executable path."""
196-
cls.setup(path=path)
193+
_git_exec_env_var = "GIT_PYTHON_GIT_EXECUTABLE"
194+
GIT_PYTHON_GIT_EXECUTABLE = None
195+
# note that the git executable is actually found during the setup step in
196+
# the top level __init__
197197

198198
@classmethod
199-
def setup(cls, path=None):
200-
"""Convenience method for setting the git executable path."""
199+
def refresh(cls, path=None):
200+
"""This gets called by the setup function (see the top level __init__).
201+
"""
202+
# discern which path to refresh with
201203
if path is not None:
202-
# use the path the user gave
203-
os.environ[cls._git_exec_env_var] = path
204-
elif cls._git_exec_env_var in os.environ:
205-
# fall back to the environment variable that's already set
206-
pass
204+
new_git = os.path.abspath(path)
207205
else:
208-
# hope that git can be found on the user's $PATH
209-
pass
206+
new_git = os.environ.get(cls._git_exec_env_var, cls.git_exec_name)
210207

208+
# keep track of the old and new git executable path
211209
old_git = cls.GIT_PYTHON_GIT_EXECUTABLE
212-
new_git = os.environ.get(cls._git_exec_env_var, cls.git_exec_name)
213210
cls.GIT_PYTHON_GIT_EXECUTABLE = new_git
214211

212+
# test if the new git executable path is valid
215213
has_git = False
216214
try:
217215
cls().version()
218216
has_git = True
219217
except GitCommandNotFound:
220218
pass
221219

220+
# warn or raise exception if test failed
222221
if not has_git:
223222
err = dedent("""\
224223
Bad git executable. The git executable must be specified in one of the following ways:
225224
(1) be included in your $PATH, or
226225
(2) be set via $GIT_PYTHON_GIT_EXECUTABLE, or
227-
(3) explicitly call git.cmd.setup with the full path.
226+
(3) explicitly set via git.setup (or git.refresh).
228227
""")
229228

230229
if old_git is None:
231230
# on the first setup (when GIT_PYTHON_GIT_EXECUTABLE is
232231
# None) we only warn the user and simply set the default
233232
# executable
234233
cls.GIT_PYTHON_GIT_EXECUTABLE = cls.git_exec_name
235-
print("WARNING: %s" % err)
234+
print(dedent("""\
235+
WARNING: %s
236+
All git commands will error until this is rectified.
237+
""") % err)
236238
else:
237239
# after the first setup (when GIT_PYTHON_GIT_EXECUTABLE
238240
# is no longer None) we raise an exception and reset the
239241
# GIT_PYTHON_GIT_EXECUTABLE to whatever the value was
240242
# previously
241-
cls.GIT_PYTHON_GIT_EXECUTABLE = old_name
243+
cls.GIT_PYTHON_GIT_EXECUTABLE = old_git
242244
raise GitCommandNotFound("git", err)
243245

244-
_git_exec_env_var = "GIT_PYTHON_GIT_EXECUTABLE"
245-
# immediately set with the default value ("git")
246-
GIT_PYTHON_GIT_EXECUTABLE = None
247-
# see the setup performed below
246+
return has_git
248247

249248
@classmethod
250249
def is_cygwin(cls):
@@ -1024,16 +1023,3 @@ def clear_cache(self):
10241023
self.cat_file_all = None
10251024
self.cat_file_header = None
10261025
return self
1027-
1028-
1029-
1030-
# this is where the git executable is setup
1031-
def setup(path=None):
1032-
Git.setup(path=path)
1033-
1034-
1035-
def refresh(path=None):
1036-
Git.refresh(path=path)
1037-
1038-
1039-
setup()

‎git/remote.py

+30-10
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,37 @@ class FetchInfo(object):
210210

211211
re_fetch_result = re.compile(r'^\s*(.) (\[?[\w\s\.$@]+\]?)\s+(.+) -> ([^\s]+)( \(.*\)?$)?')
212212

213-
_flag_map = {'!': ERROR,
214-
'+': FORCED_UPDATE,
215-
'*': 0,
216-
'=': HEAD_UPTODATE,
217-
' ': FAST_FORWARD}
213+
_flag_map = {
214+
'!': ERROR,
215+
'+': FORCED_UPDATE,
216+
'*': 0,
217+
'=': HEAD_UPTODATE,
218+
' ': FAST_FORWARD,
219+
'-': TAG_UPDATE,
220+
}
218221

219-
v = Git().version_info[:2]
220-
if v >= (2, 10):
221-
_flag_map['t'] = TAG_UPDATE
222-
else:
223-
_flag_map['-'] = TAG_UPDATE
222+
@classmethod
223+
def refresh(cls):
224+
"""This gets called by the setup function (see the top level __init__).
225+
"""
226+
# clear the old values in _flag_map
227+
try:
228+
del cls._flag_map["t"]
229+
except KeyError:
230+
pass
231+
232+
try:
233+
del cls._flag_map["-"]
234+
except KeyError:
235+
pass
236+
237+
# set the value given the git version
238+
if Git().version_info[:2] >= (2, 10):
239+
cls._flag_map["t"] = cls.TAG_UPDATE
240+
else:
241+
cls._flag_map["-"] = cls.TAG_UPDATE
242+
243+
return True
224244

225245
def __init__(self, ref, flags, note='', old_commit=None, remote_ref_path=None):
226246
"""

0 commit comments

Comments
 (0)