Clarify Git.execute and Popen arguments by EliahKagan · Pull Request #1688 · gitpython-developers/GitPython
:return: result of finalizer :param process: subprocess.Popen instance
@classmethod def refresh(cls, path: Union[None, PathLike] = None) -> bool: """This gets called by the refresh function (see the top level __init__). """ """This gets called by the refresh function (see the top level __init__).""" # discern which path to refresh with if path is not None: new_git = os.path.expanduser(path)
Windows might create config-files containing paths with backslashed, Windows might create config files containing paths with backslashes, but git stops liking them as it will escape the backslashes. Hence we undo the escaping just to be sure. """
Apart from the usual protocols (http, git, ssh), Git allows "remote helpers" that have the form `<transport>::<address>`, one of these helpers (`ext::`) can be used to invoke any arbitrary command. Git allows "remote helpers" that have the form ``<transport>::<address>``, one of these helpers (``ext::``) can be used to invoke any arbitrary command.
See:
def _terminate(self) -> None: """Terminate the underlying process""" """Terminate the underlying process.""" if self.proc is None: return
:param stderr: Previously read value of stderr, in case stderr is already closed. :warn: may deadlock if output or error pipes are used and not handled separately. :warn: May deadlock if output or error pipes are used and not handled separately. :raise GitCommandError: if the return status is not 0""" if stderr is None: stderr_b = b""
class CatFileContentStream(object):
"""Object representing a sized read-only stream returning the contents of an object. It behaves like a stream, but counts the data read and simulates an empty stream once our sized content region is empty. If not all data is read to the end of the objects's lifetime, we read the rest to assure the underlying stream continues to work""" If not all data is read to the end of the object's lifetime, we read the rest to assure the underlying stream continues to work."""
__slots__: Tuple[str, ...] = ("_stream", "_nbr", "_size")
def set_persistent_git_options(self, **kwargs: Any) -> None: """Specify command line options to the git executable for subsequent subcommand calls for subsequent subcommand calls.
:param kwargs: is a dict of keyword arguments. these arguments are passed as in _call_process These arguments are passed as in _call_process but will be passed to the git command rather than the subcommand. """
@overload
:param command: The command argument list to execute. It should be a string, or a sequence of program arguments. The It should be a sequence of program arguments, or a string. The program to execute is the first item in the args sequence or string.
:param istream: Standard input filehandle passed to subprocess.Popen. Standard input filehandle passed to `subprocess.Popen`.
:param with_extended_output: Whether to return a (status, stdout, stderr) tuple.
:param stdout_as_string: if False, the commands standard output will be bytes. Otherwise, it will be decoded into a string using the default encoding (usually utf-8). If False, the command's standard output will be bytes. Otherwise, it will be decoded into a string using the default encoding (usually UTF-8). The latter can fail, if the output contains binary data.
:param kill_after_timeout: Specifies a timeout in seconds for the git command, after which the process should be killed. This will have no effect if as_process is set to True. It is set to None by default and will let the process run until the timeout is explicitly specified. This feature is not supported on Windows. It's also worth noting that kill_after_timeout uses SIGKILL, which can have negative side effects on a repository. For example, stale locks in case of ``git gc`` could render the repository incapable of accepting changes until the lock is manually removed.
:param with_stdout: If True, default True, we open stdout on the created process.
:param universal_newlines: if True, pipes will be opened as text, and lines are split at all known line endings.
:param shell: Whether to invoke commands through a shell (see `Popen(..., shell=True)`). It overrides :attr:`USE_SHELL` if it is not `None`.
:param env: A dictionary of environment variables to be passed to `subprocess.Popen`.
:param strip_newline_in_stdout: Whether to strip the trailing ``\\n`` of the command stdout.
:param subprocess_kwargs: Keyword arguments to be passed to subprocess.Popen. Please note that some of the valid kwargs are already set by this method, the ones you Keyword arguments to be passed to `subprocess.Popen`. Please note that some of the valid kwargs are already set by this method; the ones you specify may not be the same ones.
:param with_stdout: If True, default True, we open stdout on the created process :param universal_newlines: if True, pipes will be opened as text, and lines are split at all known line endings. :param shell: Whether to invoke commands through a shell (see `Popen(..., shell=True)`). It overrides :attr:`USE_SHELL` if it is not `None`. :param kill_after_timeout: To specify a timeout in seconds for the git command, after which the process should be killed. This will have no effect if as_process is set to True. It is set to None by default and will let the process run until the timeout is explicitly specified. This feature is not supported on Windows. It's also worth noting that kill_after_timeout uses SIGKILL, which can have negative side effects on a repository. For example, stale locks in case of git gc could render the repository incapable of accepting changes until the lock is manually removed. :param strip_newline_in_stdout: Whether to strip the trailing ``\\n`` of the command stdout. :return: * str(output) if extended_output = False (Default) * tuple(int(status), str(stdout), str(stderr)) if extended_output = True
if output_stream is True, the stdout value will be your output stream: If output_stream is True, the stdout value will be your output stream: * output_stream if extended_output = False * tuple(int(status), output_stream, str(stderr)) if extended_output = True
Note git is executed with LC_MESSAGES="C" to ensure consistent Note that git is executed with ``LC_MESSAGES="C"`` to ensure consistent output regardless of system language.
:raise GitCommandError:
stdout_sink = PIPE if with_stdout else getattr(subprocess, "DEVNULL", None) or open(os.devnull, "wb") istream_ok = "None" if istream: istream_ok = "<valid stream>" if shell is None: shell = self.USE_SHELL log.debug( "Popen(%s, cwd=%s, universal_newlines=%s, shell=%s, istream=%s)", "Popen(%s, cwd=%s, stdin=%s, shell=%s, universal_newlines=%s)", redacted_command, cwd, universal_newlines, "<valid stream>" if istream else "None", shell, istream_ok, universal_newlines, ) try: with maybe_patch_caller_env:
def _kill_process(pid: int) -> None: """Callback method to kill a process.""" def kill_process(pid: int) -> None: """Callback to kill a process.""" p = Popen( ["ps", "--ppid", str(pid)], stdout=PIPE,
if kill_after_timeout is not None: kill_check = threading.Event() watchdog = threading.Timer(kill_after_timeout, _kill_process, args=(proc.pid,)) watchdog = threading.Timer(kill_after_timeout, kill_process, args=(proc.pid,))
# Wait for the process to return status = 0
def __call__(self, **kwargs: Any) -> "Git": """Specify command line options to the git executable for a subcommand call for a subcommand call.
:param kwargs: is a dict of keyword arguments.
:param method: is the command. Contained "_" characters will be converted to dashes,
:param kwargs: It contains key-values for the following:
def get_object_data(self, ref: str) -> Tuple[str, str, int, bytes]: """As get_object_header, but returns object data as well """As get_object_header, but returns object data as well.
:return: (hexsha, type_string, size_as_int, data_string) :note: not threadsafe"""
def stream_object_data(self, ref: str) -> Tuple[str, str, int, "Git.CatFileContentStream"]: """As get_object_header, but returns the data as a stream """As get_object_header, but returns the data as a stream.
:return: (hexsha, type_string, size_as_int, stream) :note: This method is not threadsafe, you need one independent Command instance per thread to be safe !""" :note: This method is not threadsafe, you need one independent Command instance per thread to be safe!""" cmd = self._get_persistent_cmd("cat_file_all", "cat_file", batch=True) hexsha, typename, size = self.__get_object_header(cmd, ref) cmd_stdout = cmd.stdout if cmd.stdout is not None else io.BytesIO()