Skip to content

Commit a962464

Browse files
committed
Preliminary implementation of setup/refresh functions
Added one function (setup) and an alias (refresh simply calls setup). These functions give the developer one more way to configure the git executable path. This also allows the user to interactively adjust the git executable configured during runtime as these functions dynamically update the executable path for the entire git module.
1 parent cf8dc25 commit a962464

File tree

1 file changed

+75
-8
lines changed

1 file changed

+75
-8
lines changed

Diff for: git/cmd.py

+75-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import subprocess
1818
import sys
1919
import threading
20+
from textwrap import dedent
2021

2122
from git.compat import (
2223
string_types,
@@ -182,16 +183,69 @@ def __setstate__(self, d):
182183
# Enables debugging of GitPython's git commands
183184
GIT_PYTHON_TRACE = os.environ.get("GIT_PYTHON_TRACE", False)
184185

185-
# Provide the full path to the git executable. Otherwise it assumes git is in the path
186-
_git_exec_env_var = "GIT_PYTHON_GIT_EXECUTABLE"
187-
GIT_PYTHON_GIT_EXECUTABLE = os.environ.get(_git_exec_env_var, git_exec_name)
188-
189186
# If True, a shell will be used when executing git commands.
190187
# This should only be desirable on Windows, see https://github.com/gitpython-developers/GitPython/pull/126
191188
# and check `git/test_repo.py:TestRepo.test_untracked_files()` TC for an example where it is required.
192189
# Override this value using `Git.USE_SHELL = True`
193190
USE_SHELL = False
194191

192+
# 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)
197+
198+
@classmethod
199+
def setup(cls, path=None):
200+
"""Convenience method for setting the git executable path."""
201+
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
207+
else:
208+
# hope that git can be found on the user's $PATH
209+
pass
210+
211+
old_git = cls.GIT_PYTHON_GIT_EXECUTABLE
212+
new_git = os.environ.get(cls._git_exec_env_var, cls.git_exec_name)
213+
cls.GIT_PYTHON_GIT_EXECUTABLE = new_git
214+
215+
has_git = False
216+
try:
217+
cls().version()
218+
has_git = True
219+
except GitCommandNotFound:
220+
pass
221+
222+
if not has_git:
223+
err = dedent("""\
224+
Bad git executable. The git executable must be specified in one of the following ways:
225+
(1) be included in your $PATH, or
226+
(2) be set via $GIT_PYTHON_GIT_EXECUTABLE, or
227+
(3) explicitly call git.cmd.setup with the full path.
228+
""")
229+
230+
if old_git is None:
231+
# on the first setup (when GIT_PYTHON_GIT_EXECUTABLE is
232+
# None) we only warn the user and simply set the default
233+
# executable
234+
cls.GIT_PYTHON_GIT_EXECUTABLE = cls.git_exec_name
235+
print("WARNING: %s" % err)
236+
else:
237+
# after the first setup (when GIT_PYTHON_GIT_EXECUTABLE
238+
# is no longer None) we raise an exception and reset the
239+
# GIT_PYTHON_GIT_EXECUTABLE to whatever the value was
240+
# previously
241+
cls.GIT_PYTHON_GIT_EXECUTABLE = old_name
242+
raise GitCommandNotFound("git", err)
243+
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
248+
195249
@classmethod
196250
def is_cygwin(cls):
197251
return is_cygwin_git(cls.GIT_PYTHON_GIT_EXECUTABLE)
@@ -828,13 +882,13 @@ def _call_process(self, method, *args, **kwargs):
828882
- "command options" to be converted by :meth:`transform_kwargs()`;
829883
- the `'insert_kwargs_after'` key which its value must match one of ``*args``,
830884
and any cmd-options will be appended after the matched arg.
831-
885+
832886
Examples::
833-
887+
834888
git.rev_list('master', max_count=10, header=True)
835-
889+
836890
turns into::
837-
891+
838892
git rev-list max-count 10 --header master
839893
840894
:return: Same as ``execute``"""
@@ -970,3 +1024,16 @@ def clear_cache(self):
9701024
self.cat_file_all = None
9711025
self.cat_file_header = None
9721026
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()

0 commit comments

Comments
 (0)