|  | 
| 4 | 4 | # | 
| 5 | 5 | # This module is part of GitPython and is released under | 
| 6 | 6 | # the BSD License: http://www.opensource.org/licenses/bsd-license.php | 
|  | 7 | +import contextlib | 
| 7 | 8 | import os | 
|  | 9 | +import shutil | 
| 8 | 10 | import subprocess | 
| 9 | 11 | import sys | 
| 10 |  | -from tempfile import TemporaryFile | 
|  | 12 | +from tempfile import TemporaryDirectory, TemporaryFile | 
| 11 | 13 | from unittest import mock | 
| 12 | 14 | 
 | 
| 13 | 15 | from git import Git, refresh, GitCommandError, GitCommandNotFound, Repo, cmd | 
|  | 
| 20 | 22 | from git.compat import is_win | 
| 21 | 23 | 
 | 
| 22 | 24 | 
 | 
|  | 25 | +@contextlib.contextmanager | 
|  | 26 | +def _chdir(new_dir): | 
|  | 27 | +    """Context manager to temporarily change directory. Not reentrant.""" | 
|  | 28 | +    old_dir = os.getcwd() | 
|  | 29 | +    os.chdir(new_dir) | 
|  | 30 | +    try: | 
|  | 31 | +        yield | 
|  | 32 | +    finally: | 
|  | 33 | +        os.chdir(old_dir) | 
|  | 34 | + | 
|  | 35 | + | 
| 23 | 36 | class TestGit(TestBase): | 
| 24 | 37 |     @classmethod | 
| 25 | 38 |     def setUpClass(cls): | 
| @@ -75,6 +88,23 @@ def test_it_transforms_kwargs_into_git_command_arguments(self): | 
| 75 | 88 |     def test_it_executes_git_to_shell_and_returns_result(self): | 
| 76 | 89 |         self.assertRegex(self.git.execute(["git", "version"]), r"^git version [\d\.]{2}.*$") | 
| 77 | 90 | 
 | 
|  | 91 | +    def test_it_executes_git_not_from_cwd(self): | 
|  | 92 | +        with TemporaryDirectory() as tmpdir: | 
|  | 93 | +            if is_win: | 
|  | 94 | +                # Copy an actual binary executable that is not git. | 
|  | 95 | +                other_exe_path = os.path.join(os.getenv("WINDIR"), "system32", "hostname.exe") | 
|  | 96 | +                impostor_path = os.path.join(tmpdir, "git.exe") | 
|  | 97 | +                shutil.copy(other_exe_path, impostor_path) | 
|  | 98 | +            else: | 
|  | 99 | +                # Create a shell script that doesn't do anything. | 
|  | 100 | +                impostor_path = os.path.join(tmpdir, "git") | 
|  | 101 | +                with open(impostor_path, mode="w", encoding="utf-8") as file: | 
|  | 102 | +                    print("#!/bin/sh", file=file) | 
|  | 103 | +                os.chmod(impostor_path, 0o755) | 
|  | 104 | + | 
|  | 105 | +            with _chdir(tmpdir): | 
|  | 106 | +                self.assertRegex(self.git.execute(["git", "version"]), r"^git version [\d\.]{2}.*$") | 
|  | 107 | + | 
| 78 | 108 |     def test_it_accepts_stdin(self): | 
| 79 | 109 |         filename = fixture_path("cat_file_blob") | 
| 80 | 110 |         with open(filename, "r") as fh: | 
|  | 
0 commit comments