Skip to content

Commit

Permalink
Merge pull request #4666 from cjerdonek/issue-1130-git-dir-env-vars
Browse files Browse the repository at this point in the history
Address issue #1130 (GIT_DIR and GIT_WORK_TREE).
  • Loading branch information
xavfernandez committed Oct 3, 2017
2 parents 77dad64 + 6a0d3aa commit 90f64b4
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 2 deletions.
2 changes: 2 additions & 0 deletions news/1130.bugfix
@@ -0,0 +1,2 @@
Allow pip to work if the ``GIT_DIR`` and ``GIT_WORK_TREE`` environment
variables are set.
11 changes: 10 additions & 1 deletion src/pip/_internal/utils/misc.py
Expand Up @@ -627,7 +627,14 @@ def unpack_file(filename, location, content_type, link):
def call_subprocess(cmd, show_stdout=True, cwd=None,
on_returncode='raise',
command_desc=None,
extra_environ=None, spinner=None):
extra_environ=None, unset_environ=None, spinner=None):
"""
Args:
unset_environ: an iterable of environment variable names to unset
prior to calling subprocess.Popen().
"""
if unset_environ is None:
unset_environ = []
# This function's handling of subprocess output is confusing and I
# previously broke it terribly, so as penance I will write a long comment
# explaining things.
Expand Down Expand Up @@ -664,6 +671,8 @@ def call_subprocess(cmd, show_stdout=True, cwd=None,
env = os.environ.copy()
if extra_environ:
env.update(extra_environ)
for name in unset_environ:
env.pop(name, None)
try:
proc = subprocess.Popen(
cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout,
Expand Down
5 changes: 4 additions & 1 deletion src/pip/_internal/vcs/__init__.py
Expand Up @@ -166,6 +166,8 @@ class VersionControl(object):
dirname = ''
# List of supported schemes for this Version Control
schemes = () # type: Tuple[str, ...]
# Iterable of environment variable names to pass to call_subprocess().
unset_environ = () # type: Tuple[str, ...]
default_arg_rev = None # type: Optional[str]

def __init__(self, url=None, *args, **kwargs):
Expand Down Expand Up @@ -422,7 +424,8 @@ def run_command(self, cmd, show_stdout=True, cwd=None,
return call_subprocess(cmd, show_stdout, cwd,
on_returncode,
command_desc, extra_environ,
spinner)
unset_environ=self.unset_environ,
spinner=spinner)
except OSError as e:
# errno.ENOENT = no such file or directory
# In other words, the VCS executable isn't available
Expand Down
3 changes: 3 additions & 0 deletions src/pip/_internal/vcs/git.py
Expand Up @@ -27,6 +27,9 @@ class Git(VersionControl):
schemes = (
'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file',
)
# Prevent the user's environment variables from interfering with pip:
# https://github.com/pypa/pip/issues/1130
unset_environ = ('GIT_DIR', 'GIT_WORK_TREE')
default_arg_rev = 'origin/HEAD'

def __init__(self, url=None, *args, **kwargs):
Expand Down
32 changes: 32 additions & 0 deletions tests/functional/test_vcs.py
@@ -0,0 +1,32 @@
import os

from pip._internal.utils.temp_dir import TempDirectory
from pip._internal.vcs.git import Git


def test_git_dir_ignored():
"""
Test that a GIT_DIR environment variable is ignored.
"""
git = Git()
with TempDirectory() as temp:
temp_dir = temp.path
env = {'GIT_DIR': 'foo'}
# If GIT_DIR is not ignored, then os.listdir() will return ['foo'].
git.run_command(['init', temp_dir], cwd=temp_dir, extra_environ=env)
assert os.listdir(temp_dir) == ['.git']


def test_git_work_tree_ignored():
"""
Test that a GIT_WORK_TREE environment variable is ignored.
"""
git = Git()
with TempDirectory() as temp:
temp_dir = temp.path
git.run_command(['init', temp_dir], cwd=temp_dir)
# Choose a directory relative to the cwd that does not exist.
# If GIT_WORK_TREE is not ignored, then the command will error out
# with: "fatal: This operation must be run in a work tree".
env = {'GIT_WORK_TREE': 'foo'}
git.run_command(['status', temp_dir], extra_environ=env, cwd=temp_dir)

0 comments on commit 90f64b4

Please sign in to comment.