2008-10-21 14:00:00 +00:00
|
|
|
# Copyright (C) 2008 The Android Open Source Project
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
|
2021-05-06 04:28:32 +00:00
|
|
|
import functools
|
2008-10-21 14:00:00 +00:00
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import subprocess
|
2022-11-15 23:57:22 +00:00
|
|
|
from typing import Any, Optional
|
2016-11-01 18:23:38 +00:00
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
from error import GitError
|
2019-10-01 02:39:49 +00:00
|
|
|
from git_refs import HEAD
|
2016-11-01 18:23:38 +00:00
|
|
|
import platform_utils
|
2019-08-27 04:26:15 +00:00
|
|
|
from repo_trace import REPO_TRACE, IsTrace, Trace
|
2014-01-30 22:46:03 +00:00
|
|
|
from wrapper import Wrapper
|
2008-10-21 14:00:00 +00:00
|
|
|
|
|
|
|
GIT = 'git'
|
2020-02-11 23:51:08 +00:00
|
|
|
# NB: These do not need to be kept in sync with the repo launcher script.
|
|
|
|
# These may be much newer as it allows the repo launcher to roll between
|
|
|
|
# different repo releases while source versions might require a newer git.
|
|
|
|
#
|
|
|
|
# The soft version is when we start warning users that the version is old and
|
|
|
|
# we'll be dropping support for it. We'll refuse to work with versions older
|
|
|
|
# than the hard version.
|
|
|
|
#
|
|
|
|
# git-1.7 is in (EOL) Ubuntu Precise. git-1.9 is in Ubuntu Trusty.
|
|
|
|
MIN_GIT_VERSION_SOFT = (1, 9, 1)
|
|
|
|
MIN_GIT_VERSION_HARD = (1, 7, 2)
|
2008-10-21 14:00:00 +00:00
|
|
|
GIT_DIR = 'GIT_DIR'
|
|
|
|
|
|
|
|
LAST_GITDIR = None
|
|
|
|
LAST_CWD = None
|
|
|
|
|
2020-02-12 06:20:19 +00:00
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
class _GitCall(object):
|
2021-05-06 04:28:32 +00:00
|
|
|
@functools.lru_cache(maxsize=None)
|
2011-09-19 15:05:31 +00:00
|
|
|
def version_tuple(self):
|
2021-05-06 04:28:32 +00:00
|
|
|
ret = Wrapper().ParseGitVersion()
|
|
|
|
if ret is None:
|
|
|
|
print('fatal: unable to detect git version', file=sys.stderr)
|
|
|
|
sys.exit(1)
|
|
|
|
return ret
|
2011-09-19 15:05:31 +00:00
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
def __getattr__(self, name):
|
2020-02-12 05:31:05 +00:00
|
|
|
name = name.replace('_', '-')
|
2020-02-12 06:20:19 +00:00
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
def fun(*cmdv):
|
|
|
|
command = [name]
|
|
|
|
command.extend(cmdv)
|
|
|
|
return GitCommand(None, command).Wait() == 0
|
|
|
|
return fun
|
2020-02-12 06:20:19 +00:00
|
|
|
|
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
git = _GitCall()
|
|
|
|
|
2019-07-10 21:10:07 +00:00
|
|
|
|
2019-10-01 02:39:49 +00:00
|
|
|
def RepoSourceVersion():
|
|
|
|
"""Return the version of the repo.git tree."""
|
|
|
|
ver = getattr(RepoSourceVersion, 'version', None)
|
2019-07-10 21:10:07 +00:00
|
|
|
|
2019-10-01 02:39:49 +00:00
|
|
|
# We avoid GitCommand so we don't run into circular deps -- GitCommand needs
|
|
|
|
# to initialize version info we provide.
|
|
|
|
if ver is None:
|
|
|
|
env = GitCommand._GetBasicEnv()
|
2019-07-10 21:10:07 +00:00
|
|
|
|
2019-10-01 02:39:49 +00:00
|
|
|
proj = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
env[GIT_DIR] = os.path.join(proj, '.git')
|
2021-02-16 07:38:21 +00:00
|
|
|
result = subprocess.run([GIT, 'describe', HEAD], stdout=subprocess.PIPE,
|
Add the ability to administratively enroll repo into using superproject.
Repo will remember a choice and an expiration time of the choice, per
user, about whether to use superproject by default. When not specified
from command line and the choice is not expired, repo would use the
user default value.
When a user default value is not present and when the system wide
enable default is provided in git's system configuration, repo would
ask the user for a confirmation which will be valid for two weeks.
git_config.py: Add support for system config. When reading system
config, we would use --system to avoid hardcoding a path as the
value may be different on some other distributions.
git_superproject.py: Add a new subroutine, _UseSuperproject(), which
returns whether superproject should be used and whether it
is from a user configuration.
The value is determined in the following order:
1. If the user specifies either --use-superproject or
--no-use-superproject, then that choice is being used.
2. If neither is specified, we would then check the saved value
(upon repo init) and use that choice when there was a choice.
3. We then check if there is a saved and unexpired value for
user's choice in their ~/.gitconfig, and use the unexpired
choice, if available.
4. Finally, if all the above didn't give us a decision, and if
the git system configuration is providing a rollout hint, present
a prompt to user for their decision and save it in ~/.gitconfig.
subcmds/sync.py: Make use of the new UseSuperproject() provided by
git_superproject.py.
While there also silent stderr from git describe when determining the
version of repo.
Bug: [google internal] b/190688390
Change-Id: Iad3ee03026342ee500e5d65e2f0fa600d7637613
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/309762
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Xin Li <delphij@google.com>
2021-06-16 17:19:00 +00:00
|
|
|
stderr=subprocess.DEVNULL, encoding='utf-8',
|
|
|
|
env=env, check=False)
|
2021-02-16 07:38:21 +00:00
|
|
|
if result.returncode == 0:
|
|
|
|
ver = result.stdout.strip()
|
2019-10-01 02:39:49 +00:00
|
|
|
if ver.startswith('v'):
|
|
|
|
ver = ver[1:]
|
2019-07-10 21:10:07 +00:00
|
|
|
else:
|
2019-10-01 02:39:49 +00:00
|
|
|
ver = 'unknown'
|
|
|
|
setattr(RepoSourceVersion, 'version', ver)
|
2019-07-10 21:10:07 +00:00
|
|
|
|
2019-10-01 02:39:49 +00:00
|
|
|
return ver
|
2019-07-10 21:10:07 +00:00
|
|
|
|
|
|
|
|
2019-10-01 02:39:49 +00:00
|
|
|
class UserAgent(object):
|
|
|
|
"""Mange User-Agent settings when talking to external services
|
|
|
|
|
|
|
|
We follow the style as documented here:
|
|
|
|
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent
|
|
|
|
"""
|
|
|
|
|
|
|
|
_os = None
|
|
|
|
_repo_ua = None
|
2019-07-10 21:13:46 +00:00
|
|
|
_git_ua = None
|
2019-10-01 02:39:49 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def os(self):
|
|
|
|
"""The operating system name."""
|
|
|
|
if self._os is None:
|
|
|
|
os_name = sys.platform
|
|
|
|
if os_name.lower().startswith('linux'):
|
|
|
|
os_name = 'Linux'
|
|
|
|
elif os_name == 'win32':
|
|
|
|
os_name = 'Win32'
|
|
|
|
elif os_name == 'cygwin':
|
|
|
|
os_name = 'Cygwin'
|
|
|
|
elif os_name == 'darwin':
|
|
|
|
os_name = 'Darwin'
|
|
|
|
self._os = os_name
|
|
|
|
|
|
|
|
return self._os
|
|
|
|
|
|
|
|
@property
|
|
|
|
def repo(self):
|
|
|
|
"""The UA when connecting directly from repo."""
|
|
|
|
if self._repo_ua is None:
|
|
|
|
py_version = sys.version_info
|
|
|
|
self._repo_ua = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % (
|
|
|
|
RepoSourceVersion(),
|
|
|
|
self.os,
|
|
|
|
git.version_tuple().full,
|
|
|
|
py_version.major, py_version.minor, py_version.micro)
|
|
|
|
|
|
|
|
return self._repo_ua
|
|
|
|
|
2019-07-10 21:13:46 +00:00
|
|
|
@property
|
|
|
|
def git(self):
|
|
|
|
"""The UA when running git."""
|
|
|
|
if self._git_ua is None:
|
|
|
|
self._git_ua = 'git/%s (%s) git-repo/%s' % (
|
|
|
|
git.version_tuple().full,
|
|
|
|
self.os,
|
|
|
|
RepoSourceVersion())
|
|
|
|
|
|
|
|
return self._git_ua
|
|
|
|
|
2020-02-12 06:20:19 +00:00
|
|
|
|
2019-10-01 02:39:49 +00:00
|
|
|
user_agent = UserAgent()
|
2019-07-10 21:10:07 +00:00
|
|
|
|
2020-02-12 06:20:19 +00:00
|
|
|
|
2019-06-03 18:24:30 +00:00
|
|
|
def git_require(min_version, fail=False, msg=''):
|
2011-09-19 15:05:31 +00:00
|
|
|
git_version = git.version_tuple()
|
|
|
|
if min_version <= git_version:
|
2009-06-12 16:32:50 +00:00
|
|
|
return True
|
|
|
|
if fail:
|
2012-10-25 03:40:51 +00:00
|
|
|
need = '.'.join(map(str, min_version))
|
2019-06-03 18:24:30 +00:00
|
|
|
if msg:
|
|
|
|
msg = ' for ' + msg
|
|
|
|
print('fatal: git %s or later required%s' % (need, msg), file=sys.stderr)
|
2009-06-12 16:32:50 +00:00
|
|
|
sys.exit(1)
|
|
|
|
return False
|
|
|
|
|
2020-02-12 06:20:19 +00:00
|
|
|
|
2022-11-15 23:57:22 +00:00
|
|
|
def _build_env(
|
|
|
|
_kwargs_only=(),
|
|
|
|
bare: Optional[bool] = False,
|
|
|
|
disable_editor: Optional[bool] = False,
|
|
|
|
ssh_proxy: Optional[Any] = None,
|
|
|
|
gitdir: Optional[str] = None,
|
|
|
|
objdir: Optional[str] = None
|
|
|
|
):
|
|
|
|
"""Constucts an env dict for command execution."""
|
|
|
|
|
|
|
|
assert _kwargs_only == (), '_build_env only accepts keyword arguments.'
|
|
|
|
|
|
|
|
env = GitCommand._GetBasicEnv()
|
|
|
|
|
|
|
|
if disable_editor:
|
|
|
|
env['GIT_EDITOR'] = ':'
|
|
|
|
if ssh_proxy:
|
|
|
|
env['REPO_SSH_SOCK'] = ssh_proxy.sock()
|
|
|
|
env['GIT_SSH'] = ssh_proxy.proxy
|
|
|
|
env['GIT_SSH_VARIANT'] = 'ssh'
|
|
|
|
if 'http_proxy' in env and 'darwin' == sys.platform:
|
|
|
|
s = "'http.proxy=%s'" % (env['http_proxy'],)
|
|
|
|
p = env.get('GIT_CONFIG_PARAMETERS')
|
|
|
|
if p is not None:
|
|
|
|
s = p + ' ' + s
|
|
|
|
env['GIT_CONFIG_PARAMETERS'] = s
|
|
|
|
if 'GIT_ALLOW_PROTOCOL' not in env:
|
|
|
|
env['GIT_ALLOW_PROTOCOL'] = (
|
|
|
|
'file:git:http:https:ssh:persistent-http:persistent-https:sso:rpc')
|
|
|
|
env['GIT_HTTP_USER_AGENT'] = user_agent.git
|
|
|
|
|
|
|
|
if objdir:
|
|
|
|
# Set to the place we want to save the objects.
|
|
|
|
env['GIT_OBJECT_DIRECTORY'] = objdir
|
|
|
|
|
|
|
|
alt_objects = os.path.join(gitdir, 'objects') if gitdir else None
|
|
|
|
if (alt_objects and
|
|
|
|
os.path.realpath(alt_objects) != os.path.realpath(objdir)):
|
|
|
|
# Allow git to search the original place in case of local or unique refs
|
|
|
|
# that git will attempt to resolve even if we aren't fetching them.
|
|
|
|
env['GIT_ALTERNATE_OBJECT_DIRECTORIES'] = alt_objects
|
|
|
|
if bare and gitdir is not None:
|
|
|
|
env[GIT_DIR] = gitdir
|
|
|
|
|
|
|
|
return env
|
|
|
|
|
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
class GitCommand(object):
|
2020-12-08 03:04:55 +00:00
|
|
|
"""Wrapper around a single git invocation."""
|
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
def __init__(self,
|
|
|
|
project,
|
|
|
|
cmdv,
|
2020-02-12 04:56:59 +00:00
|
|
|
bare=False,
|
2021-02-16 20:38:53 +00:00
|
|
|
input=None,
|
2020-02-12 04:56:59 +00:00
|
|
|
capture_stdout=False,
|
|
|
|
capture_stderr=False,
|
2020-02-17 06:35:18 +00:00
|
|
|
merge_output=False,
|
2020-02-12 04:56:59 +00:00
|
|
|
disable_editor=False,
|
2021-05-06 04:44:42 +00:00
|
|
|
ssh_proxy=None,
|
2020-02-12 04:56:59 +00:00
|
|
|
cwd=None,
|
project: store objects in project-objects directly
In order to stop sharing objects/ directly between shared projects,
we have to fetch the remote objects into project-objects/ manually.
So instead of running git operations in the individual project dirs
and relying on .git/objects being symlinked to project-objects/,
tell git to store any objects it fetches in project-objects/.
We do this by leveraging the GIT_OBJECT_DIRECTORY override. This
has been in git forever, or at least since v1.7.2 which is what we
already hard require. This tells git to save new objects to the
specified path no matter where it's being run otherwise.
We still otherwise run git in the project-specific dir so that it
can find the right set of refs that it wants to compare against,
including local refs. For that reason, we also have to leverage
GIT_ALTERNATE_OBJECT_DIRECTORIES to tell git where to find objects
that are not in the upstream remote. This way git doesn't blow up
when it can't find objects only associated with local commits.
As it stands right now, the practical result is the same: since we
symlink the project objects/ dir to the project-objects/ tree, the
default objects dir, the one we set $GIT_OBJECT_DIRECTORY to, and
the one we set $GIT_ALTERNATE_OBJECT_DIRECTORIES to are actually
all the same. So this commit by itself should be safe. But in a
follow up commit, we can replace the symlink with a separate dir
and git will keep working.
Bug: https://crbug.com/gerrit/15553
Change-Id: Ie4e654aec3e1ee307eee925a54908a2db6a5869f
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/328100
Reviewed-by: Jack Neus <jackneus@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
2021-12-23 22:36:09 +00:00
|
|
|
gitdir=None,
|
|
|
|
objdir=None):
|
2008-10-21 14:00:00 +00:00
|
|
|
|
|
|
|
if project:
|
|
|
|
if not cwd:
|
|
|
|
cwd = project.worktree
|
|
|
|
if not gitdir:
|
|
|
|
gitdir = project.gitdir
|
2022-11-15 23:57:22 +00:00
|
|
|
|
project: store objects in project-objects directly
In order to stop sharing objects/ directly between shared projects,
we have to fetch the remote objects into project-objects/ manually.
So instead of running git operations in the individual project dirs
and relying on .git/objects being symlinked to project-objects/,
tell git to store any objects it fetches in project-objects/.
We do this by leveraging the GIT_OBJECT_DIRECTORY override. This
has been in git forever, or at least since v1.7.2 which is what we
already hard require. This tells git to save new objects to the
specified path no matter where it's being run otherwise.
We still otherwise run git in the project-specific dir so that it
can find the right set of refs that it wants to compare against,
including local refs. For that reason, we also have to leverage
GIT_ALTERNATE_OBJECT_DIRECTORIES to tell git where to find objects
that are not in the upstream remote. This way git doesn't blow up
when it can't find objects only associated with local commits.
As it stands right now, the practical result is the same: since we
symlink the project objects/ dir to the project-objects/ tree, the
default objects dir, the one we set $GIT_OBJECT_DIRECTORY to, and
the one we set $GIT_ALTERNATE_OBJECT_DIRECTORIES to are actually
all the same. So this commit by itself should be safe. But in a
follow up commit, we can replace the symlink with a separate dir
and git will keep working.
Bug: https://crbug.com/gerrit/15553
Change-Id: Ie4e654aec3e1ee307eee925a54908a2db6a5869f
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/328100
Reviewed-by: Jack Neus <jackneus@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
2021-12-23 22:36:09 +00:00
|
|
|
# Git on Windows wants its paths only using / for reliability.
|
|
|
|
if platform_utils.isWindows():
|
|
|
|
if objdir:
|
|
|
|
objdir = objdir.replace('\\', '/')
|
|
|
|
if gitdir:
|
|
|
|
gitdir = gitdir.replace('\\', '/')
|
|
|
|
|
2022-11-15 23:57:22 +00:00
|
|
|
env = _build_env(
|
|
|
|
disable_editor=disable_editor,
|
|
|
|
ssh_proxy=ssh_proxy,
|
|
|
|
objdir=objdir,
|
|
|
|
gitdir=gitdir,
|
|
|
|
bare=bare,
|
|
|
|
)
|
2008-10-21 14:00:00 +00:00
|
|
|
|
|
|
|
command = [GIT]
|
|
|
|
if bare:
|
|
|
|
cwd = None
|
2015-03-17 03:49:10 +00:00
|
|
|
command.append(cmdv[0])
|
|
|
|
# Need to use the --progress flag for fetch/clone so output will be
|
|
|
|
# displayed as by default git only does progress output if stderr is a TTY.
|
|
|
|
if sys.stderr.isatty() and cmdv[0] in ('fetch', 'clone'):
|
|
|
|
if '--progress' not in cmdv and '--quiet' not in cmdv:
|
|
|
|
command.append('--progress')
|
|
|
|
command.extend(cmdv[1:])
|
2008-10-21 14:00:00 +00:00
|
|
|
|
2021-02-16 20:38:53 +00:00
|
|
|
stdin = subprocess.PIPE if input else None
|
2021-02-16 22:18:12 +00:00
|
|
|
stdout = subprocess.PIPE if capture_stdout else None
|
|
|
|
stderr = (subprocess.STDOUT if merge_output else
|
|
|
|
(subprocess.PIPE if capture_stderr else None))
|
2008-10-21 14:00:00 +00:00
|
|
|
|
2022-11-03 20:51:19 +00:00
|
|
|
dbg = ''
|
2009-04-18 16:54:51 +00:00
|
|
|
if IsTrace():
|
2008-10-21 14:00:00 +00:00
|
|
|
global LAST_CWD
|
|
|
|
global LAST_GITDIR
|
|
|
|
|
|
|
|
if cwd and LAST_CWD != cwd:
|
|
|
|
if LAST_GITDIR or LAST_CWD:
|
|
|
|
dbg += '\n'
|
|
|
|
dbg += ': cd %s\n' % cwd
|
|
|
|
LAST_CWD = cwd
|
|
|
|
|
|
|
|
if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]:
|
|
|
|
if LAST_GITDIR or LAST_CWD:
|
|
|
|
dbg += '\n'
|
|
|
|
dbg += ': export GIT_DIR=%s\n' % env[GIT_DIR]
|
|
|
|
LAST_GITDIR = env[GIT_DIR]
|
|
|
|
|
project: store objects in project-objects directly
In order to stop sharing objects/ directly between shared projects,
we have to fetch the remote objects into project-objects/ manually.
So instead of running git operations in the individual project dirs
and relying on .git/objects being symlinked to project-objects/,
tell git to store any objects it fetches in project-objects/.
We do this by leveraging the GIT_OBJECT_DIRECTORY override. This
has been in git forever, or at least since v1.7.2 which is what we
already hard require. This tells git to save new objects to the
specified path no matter where it's being run otherwise.
We still otherwise run git in the project-specific dir so that it
can find the right set of refs that it wants to compare against,
including local refs. For that reason, we also have to leverage
GIT_ALTERNATE_OBJECT_DIRECTORIES to tell git where to find objects
that are not in the upstream remote. This way git doesn't blow up
when it can't find objects only associated with local commits.
As it stands right now, the practical result is the same: since we
symlink the project objects/ dir to the project-objects/ tree, the
default objects dir, the one we set $GIT_OBJECT_DIRECTORY to, and
the one we set $GIT_ALTERNATE_OBJECT_DIRECTORIES to are actually
all the same. So this commit by itself should be safe. But in a
follow up commit, we can replace the symlink with a separate dir
and git will keep working.
Bug: https://crbug.com/gerrit/15553
Change-Id: Ie4e654aec3e1ee307eee925a54908a2db6a5869f
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/328100
Reviewed-by: Jack Neus <jackneus@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
2021-12-23 22:36:09 +00:00
|
|
|
if 'GIT_OBJECT_DIRECTORY' in env:
|
|
|
|
dbg += ': export GIT_OBJECT_DIRECTORY=%s\n' % env['GIT_OBJECT_DIRECTORY']
|
|
|
|
if 'GIT_ALTERNATE_OBJECT_DIRECTORIES' in env:
|
|
|
|
dbg += ': export GIT_ALTERNATE_OBJECT_DIRECTORIES=%s\n' % env['GIT_ALTERNATE_OBJECT_DIRECTORIES']
|
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
dbg += ': '
|
|
|
|
dbg += ' '.join(command)
|
|
|
|
if stdin == subprocess.PIPE:
|
|
|
|
dbg += ' 0<|'
|
|
|
|
if stdout == subprocess.PIPE:
|
|
|
|
dbg += ' 1>|'
|
|
|
|
if stderr == subprocess.PIPE:
|
|
|
|
dbg += ' 2>|'
|
2020-02-17 06:35:18 +00:00
|
|
|
elif stderr == subprocess.STDOUT:
|
|
|
|
dbg += ' 2>&1'
|
2010-05-12 01:21:33 +00:00
|
|
|
|
2022-11-03 20:51:19 +00:00
|
|
|
with Trace('git command %s %s with debug: %s', LAST_GITDIR, command, dbg):
|
|
|
|
try:
|
|
|
|
p = subprocess.Popen(command,
|
|
|
|
cwd=cwd,
|
|
|
|
env=env,
|
|
|
|
encoding='utf-8',
|
|
|
|
errors='backslashreplace',
|
|
|
|
stdin=stdin,
|
|
|
|
stdout=stdout,
|
|
|
|
stderr=stderr)
|
|
|
|
except Exception as e:
|
|
|
|
raise GitError('%s: %s' % (command[1], e))
|
2008-10-21 14:00:00 +00:00
|
|
|
|
2021-05-06 04:44:42 +00:00
|
|
|
if ssh_proxy:
|
2022-11-03 20:51:19 +00:00
|
|
|
ssh_proxy.add_client(p)
|
|
|
|
|
|
|
|
self.process = p
|
|
|
|
|
|
|
|
try:
|
|
|
|
self.stdout, self.stderr = p.communicate(input=input)
|
|
|
|
finally:
|
|
|
|
if ssh_proxy:
|
|
|
|
ssh_proxy.remove_client(p)
|
|
|
|
self.rc = p.wait()
|
2021-02-16 20:45:19 +00:00
|
|
|
|
2019-10-01 02:39:49 +00:00
|
|
|
@staticmethod
|
|
|
|
def _GetBasicEnv():
|
|
|
|
"""Return a basic env for running git under.
|
|
|
|
|
|
|
|
This is guaranteed to be side-effect free.
|
|
|
|
"""
|
|
|
|
env = os.environ.copy()
|
|
|
|
for key in (REPO_TRACE,
|
|
|
|
GIT_DIR,
|
|
|
|
'GIT_ALTERNATE_OBJECT_DIRECTORIES',
|
|
|
|
'GIT_OBJECT_DIRECTORY',
|
|
|
|
'GIT_WORK_TREE',
|
|
|
|
'GIT_GRAFT_FILE',
|
|
|
|
'GIT_INDEX_FILE'):
|
|
|
|
env.pop(key, None)
|
|
|
|
return env
|
|
|
|
|
2008-10-21 14:00:00 +00:00
|
|
|
def Wait(self):
|
2021-02-16 20:45:19 +00:00
|
|
|
return self.rc
|