@@ -46,9 +46,24 @@ def _patch_out_env(name):
4646
4747@contextlib .contextmanager
4848def _rollback_refresh ():
49+ old_git_executable = Git .GIT_PYTHON_GIT_EXECUTABLE
50+
51+ if old_git_executable is None :
52+ raise RuntimeError ("no executable string (need initial refresh before test)" )
53+
4954 try :
50- yield Git . GIT_PYTHON_GIT_EXECUTABLE # Provide the old value for convenience.
55+ yield old_git_executable # Provide the old value for convenience.
5156 finally :
57+ # The cleanup refresh should always raise an exception if it fails, since if it
58+ # fails then previously discovered test results could be misleading and, more
59+ # importantly, subsequent tests may be unable to run or give misleading results.
60+ # So pre-set a non-None value, so that the cleanup will be a "second" refresh.
61+ # This covers cases where a test has set it to None to test a "first" refresh.
62+ Git .GIT_PYTHON_GIT_EXECUTABLE = Git .git_exec_name
63+
64+ # Do the cleanup refresh. This sets Git.GIT_PYTHON_GIT_EXECUTABLE to old_value
65+ # in most cases. The reason to call it is to achieve other associated state
66+ # changes as well, which include updating attributes of the FetchInfo class.
5267 refresh ()
5368
5469
@@ -314,7 +329,51 @@ def test_cmd_override(self):
314329 ):
315330 self .assertRaises (GitCommandNotFound , self .git .version )
316331
317- def test_refresh_bad_absolute_git_path (self ):
332+ def test_refresh_from_bad_absolute_git_path_env (self ):
333+ """Bad absolute path from environment is reported and not set."""
334+ absolute_path = str (Path ("yada" ).absolute ())
335+ expected_pattern = rf"\n[ \t]*cmdline: { re .escape (absolute_path )} \Z"
336+
337+ with _rollback_refresh () as old_git_executable :
338+ with mock .patch .dict (os .environ , {"GIT_PYTHON_GIT_EXECUTABLE" : absolute_path }):
339+ with self .assertRaisesRegex (GitCommandNotFound , expected_pattern ):
340+ refresh ()
341+ self .assertEqual (self .git .GIT_PYTHON_GIT_EXECUTABLE , old_git_executable )
342+
343+ def test_refresh_from_bad_relative_git_path_env (self ):
344+ """Bad relative path from environment is kept relative and reported, not set."""
345+ # Relative paths are not resolved when refresh() is called with no arguments, so
346+ # use a string that's very unlikely to be a command name found in a path lookup.
347+ relative_path = "yada-e47e70c6-acbf-40f8-ad65-13af93c2195b"
348+ expected_pattern = rf"\n[ \t]*cmdline: { re .escape (relative_path )} \Z"
349+
350+ with _rollback_refresh () as old_git_executable :
351+ with mock .patch .dict (os .environ , {"GIT_PYTHON_GIT_EXECUTABLE" : relative_path }):
352+ with self .assertRaisesRegex (GitCommandNotFound , expected_pattern ):
353+ refresh ()
354+ self .assertEqual (self .git .GIT_PYTHON_GIT_EXECUTABLE , old_git_executable )
355+
356+ def test_refresh_from_good_absolute_git_path_env (self ):
357+ """Good absolute path from environment is set."""
358+ absolute_path = shutil .which ("git" )
359+
360+ with _rollback_refresh ():
361+ with mock .patch .dict (os .environ , {"GIT_PYTHON_GIT_EXECUTABLE" : absolute_path }):
362+ refresh ()
363+ self .assertEqual (self .git .GIT_PYTHON_GIT_EXECUTABLE , absolute_path )
364+
365+ def test_refresh_from_good_relative_git_path_env (self ):
366+ """Good relative path from environment is kept relative and set."""
367+ with _rollback_refresh ():
368+ # Set a string that wouldn't work and isn't "git".
369+ type(self .git ).GIT_PYTHON_GIT_EXECUTABLE = ""
370+
371+ # Now observe if setting the environment variable to "git" takes effect.
372+ with mock .patch .dict (os .environ , {"GIT_PYTHON_GIT_EXECUTABLE" : "git" }):
373+ refresh ()
374+ self .assertEqual (self .git .GIT_PYTHON_GIT_EXECUTABLE , "git" )
375+
376+ def test_refresh_with_bad_absolute_git_path_arg (self ):
318377 """Bad absolute path arg is reported and not set."""
319378 absolute_path = str (Path ("yada" ).absolute ())
320379 expected_pattern = rf"\n[ \t]*cmdline: { re .escape (absolute_path )} \Z"
@@ -324,7 +383,7 @@ def test_refresh_bad_absolute_git_path(self):
324383 refresh (absolute_path )
325384 self .assertEqual (self .git .GIT_PYTHON_GIT_EXECUTABLE , old_git_executable )
326385
327- def test_refresh_bad_relative_git_path (self ):
386+ def test_refresh_with_bad_relative_git_path_arg (self ):
328387 """Bad relative path arg is resolved to absolute path and reported, not set."""
329388 absolute_path = str (Path ("yada" ).absolute ())
330389 expected_pattern = rf"\n[ \t]*cmdline: { re .escape (absolute_path )} \Z"
@@ -334,15 +393,15 @@ def test_refresh_bad_relative_git_path(self):
334393 refresh ("yada" )
335394 self .assertEqual (self .git .GIT_PYTHON_GIT_EXECUTABLE , old_git_executable )
336395
337- def test_refresh_good_absolute_git_path (self ):
396+ def test_refresh_with_good_absolute_git_path_arg (self ):
338397 """Good absolute path arg is set."""
339398 absolute_path = shutil .which ("git" )
340399
341400 with _rollback_refresh ():
342401 refresh (absolute_path )
343402 self .assertEqual (self .git .GIT_PYTHON_GIT_EXECUTABLE , absolute_path )
344403
345- def test_refresh_good_relative_git_path (self ):
404+ def test_refresh_with_good_relative_git_path_arg (self ):
346405 """Good relative path arg is resolved to absolute path and set."""
347406 absolute_path = shutil .which ("git" )
348407 dirname , basename = osp .split (absolute_path )
0 commit comments