summaryrefslogtreecommitdiff
path: root/git/cmd.py
diff options
context:
space:
mode:
Diffstat (limited to 'git/cmd.py')
-rw-r--r--git/cmd.py85
1 files changed, 82 insertions, 3 deletions
diff --git a/git/cmd.py b/git/cmd.py
index 55ed74dd..960b2a21 100644
--- a/git/cmd.py
+++ b/git/cmd.py
@@ -5,6 +5,7 @@
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
import os
+import os.path
import sys
import select
import logging
@@ -12,6 +13,7 @@ import threading
import errno
import mmap
+from contextlib import contextmanager
from subprocess import (
call,
Popen,
@@ -139,7 +141,7 @@ def handle_process_output(process, stdout_handler, stderr_handler, finalizer):
if hasattr(select, 'poll'):
# poll is preferred, as select is limited to file handles up to 1024 ... . This could otherwise be
- # an issue for us, as it matters how many handles or own process has
+ # an issue for us, as it matters how many handles our own process has
poll = select.poll()
READ_ONLY = select.POLLIN | select.POLLPRI | select.POLLHUP | select.POLLERR
CLOSED = select.POLLHUP | select.POLLERR
@@ -223,7 +225,7 @@ class Git(LazyMixin):
Set its value to 'full' to see details about the returned values.
"""
__slots__ = ("_working_dir", "cat_file_all", "cat_file_header", "_version_info",
- "_git_options")
+ "_git_options", "_environment")
# CONFIGURATION
# The size in bytes read from stdout when copying git's output to another stream
@@ -413,6 +415,9 @@ class Git(LazyMixin):
self._working_dir = working_dir
self._git_options = ()
+ # Extra environment variables to pass to git commands
+ self._environment = {}
+
# cached command slots
self.cat_file_header = None
self.cat_file_all = None
@@ -434,6 +439,10 @@ class Git(LazyMixin):
super(Git, self)._set_cache_(attr)
# END handle version info
+ def _sshkey_script_path(self):
+ this_dir = os.path.dirname(__file__)
+ return os.path.join(this_dir, 'scripts', 'ssh_wrapper.sh')
+
@property
def working_dir(self):
""":return: Git directory we are working on"""
@@ -536,6 +545,8 @@ class Git(LazyMixin):
# Start the process
env = os.environ.copy()
env["LC_MESSAGES"] = "C"
+ env.update(self._environment)
+
proc = Popen(command,
env=env,
cwd=cwd,
@@ -608,6 +619,74 @@ class Git(LazyMixin):
else:
return stdout_value
+ def environment(self):
+ return self._environment
+
+ def update_environment(self, **kwargs):
+ """
+ Set environment variables for future git invocations. Return all changed
+ values in a format that can be passed back into this function to revert
+ the changes:
+
+ ``Examples``::
+
+ old_env = self.update_environment(PWD='/tmp')
+ self.update_environment(**old_env)
+
+ :param kwargs: environment variables to use for git processes
+ :return: dict that maps environment variables to their old values
+ """
+ old_env = {}
+ for key, value in kwargs.items():
+ # set value if it is None
+ if value is not None:
+ if key in self._environment:
+ old_env[key] = self._environment[key]
+ else:
+ old_env[key] = None
+ self._environment[key] = value
+ # remove key from environment if its value is None
+ elif key in self._environment:
+ old_env[key] = self._environment[key]
+ del self._environment[key]
+ return old_env
+
+ @contextmanager
+ def custom_environment(self, **kwargs):
+ """
+ A context manager around the above ``update_environment`` method to restore the
+ environment back to its previous state after operation.
+
+ ``Examples``::
+
+ with self.custom_environment(GIT_SSH='/bin/ssh_wrapper'):
+ repo.remotes.origin.fetch()
+
+ :param kwargs: see update_environment
+ """
+ old_env = self.update_environment(**kwargs)
+ try:
+ yield
+ finally:
+ self.update_environment(**old_env)
+
+ @contextmanager
+ def sshkey(self, sshkey_file_path):
+ """
+ A context manager to temporarily set an SSH key for all operations that
+ run inside it.
+
+ ``Examples``::
+
+ with self.sshkey('deployment_key'):
+ repo.remotes.origin.fetch()
+
+ :param sshkey_file_path: Path to a private SSH key file
+ """
+ ssh_wrapper = self._sshkey_script_path()
+ with self.custom_environment(GIT_SSH_KEY_FILE=sshkey_file_path, GIT_SSH=ssh_wrapper):
+ yield
+
def transform_kwargs(self, split_single_char_options=False, **kwargs):
"""Transforms Python style kwargs into git command line options."""
args = list()
@@ -731,7 +810,7 @@ class Git(LazyMixin):
import warnings
msg = "WARNING: Automatically switched to use git.cmd as git executable"
msg += ", which reduces performance by ~70%."
- msg += "Its recommended to put git.exe into the PATH or to "
+ msg += "It is recommended to put git.exe into the PATH or to "
msg += "set the %s " % self._git_exec_env_var
msg += "environment variable to the executable's location"
warnings.warn(msg)