diff options
Diffstat (limited to 'git_command.py')
-rw-r--r-- | git_command.py | 91 |
1 files changed, 5 insertions, 86 deletions
diff --git a/git_command.py b/git_command.py index f8cb280c..fabad0e0 100644 --- a/git_command.py +++ b/git_command.py | |||
@@ -14,16 +14,14 @@ | |||
14 | 14 | ||
15 | import functools | 15 | import functools |
16 | import os | 16 | import os |
17 | import re | ||
18 | import sys | 17 | import sys |
19 | import subprocess | 18 | import subprocess |
20 | import tempfile | ||
21 | from signal import SIGTERM | ||
22 | 19 | ||
23 | from error import GitError | 20 | from error import GitError |
24 | from git_refs import HEAD | 21 | from git_refs import HEAD |
25 | import platform_utils | 22 | import platform_utils |
26 | from repo_trace import REPO_TRACE, IsTrace, Trace | 23 | from repo_trace import REPO_TRACE, IsTrace, Trace |
24 | import ssh | ||
27 | from wrapper import Wrapper | 25 | from wrapper import Wrapper |
28 | 26 | ||
29 | GIT = 'git' | 27 | GIT = 'git' |
@@ -43,85 +41,6 @@ GIT_DIR = 'GIT_DIR' | |||
43 | LAST_GITDIR = None | 41 | LAST_GITDIR = None |
44 | LAST_CWD = None | 42 | LAST_CWD = None |
45 | 43 | ||
46 | _ssh_proxy_path = None | ||
47 | _ssh_sock_path = None | ||
48 | _ssh_clients = [] | ||
49 | |||
50 | |||
51 | def _run_ssh_version(): | ||
52 | """run ssh -V to display the version number""" | ||
53 | return subprocess.check_output(['ssh', '-V'], stderr=subprocess.STDOUT).decode() | ||
54 | |||
55 | |||
56 | def _parse_ssh_version(ver_str=None): | ||
57 | """parse a ssh version string into a tuple""" | ||
58 | if ver_str is None: | ||
59 | ver_str = _run_ssh_version() | ||
60 | m = re.match(r'^OpenSSH_([0-9.]+)(p[0-9]+)?\s', ver_str) | ||
61 | if m: | ||
62 | return tuple(int(x) for x in m.group(1).split('.')) | ||
63 | else: | ||
64 | return () | ||
65 | |||
66 | |||
67 | @functools.lru_cache(maxsize=None) | ||
68 | def ssh_version(): | ||
69 | """return ssh version as a tuple""" | ||
70 | try: | ||
71 | return _parse_ssh_version() | ||
72 | except subprocess.CalledProcessError: | ||
73 | print('fatal: unable to detect ssh version', file=sys.stderr) | ||
74 | sys.exit(1) | ||
75 | |||
76 | |||
77 | def ssh_sock(create=True): | ||
78 | global _ssh_sock_path | ||
79 | if _ssh_sock_path is None: | ||
80 | if not create: | ||
81 | return None | ||
82 | tmp_dir = '/tmp' | ||
83 | if not os.path.exists(tmp_dir): | ||
84 | tmp_dir = tempfile.gettempdir() | ||
85 | if ssh_version() < (6, 7): | ||
86 | tokens = '%r@%h:%p' | ||
87 | else: | ||
88 | tokens = '%C' # hash of %l%h%p%r | ||
89 | _ssh_sock_path = os.path.join( | ||
90 | tempfile.mkdtemp('', 'ssh-', tmp_dir), | ||
91 | 'master-' + tokens) | ||
92 | return _ssh_sock_path | ||
93 | |||
94 | |||
95 | def _ssh_proxy(): | ||
96 | global _ssh_proxy_path | ||
97 | if _ssh_proxy_path is None: | ||
98 | _ssh_proxy_path = os.path.join( | ||
99 | os.path.dirname(__file__), | ||
100 | 'git_ssh') | ||
101 | return _ssh_proxy_path | ||
102 | |||
103 | |||
104 | def _add_ssh_client(p): | ||
105 | _ssh_clients.append(p) | ||
106 | |||
107 | |||
108 | def _remove_ssh_client(p): | ||
109 | try: | ||
110 | _ssh_clients.remove(p) | ||
111 | except ValueError: | ||
112 | pass | ||
113 | |||
114 | |||
115 | def terminate_ssh_clients(): | ||
116 | global _ssh_clients | ||
117 | for p in _ssh_clients: | ||
118 | try: | ||
119 | os.kill(p.pid, SIGTERM) | ||
120 | p.wait() | ||
121 | except OSError: | ||
122 | pass | ||
123 | _ssh_clients = [] | ||
124 | |||
125 | 44 | ||
126 | class _GitCall(object): | 45 | class _GitCall(object): |
127 | @functools.lru_cache(maxsize=None) | 46 | @functools.lru_cache(maxsize=None) |
@@ -256,8 +175,8 @@ class GitCommand(object): | |||
256 | if disable_editor: | 175 | if disable_editor: |
257 | env['GIT_EDITOR'] = ':' | 176 | env['GIT_EDITOR'] = ':' |
258 | if ssh_proxy: | 177 | if ssh_proxy: |
259 | env['REPO_SSH_SOCK'] = ssh_sock() | 178 | env['REPO_SSH_SOCK'] = ssh.sock() |
260 | env['GIT_SSH'] = _ssh_proxy() | 179 | env['GIT_SSH'] = ssh.proxy() |
261 | env['GIT_SSH_VARIANT'] = 'ssh' | 180 | env['GIT_SSH_VARIANT'] = 'ssh' |
262 | if 'http_proxy' in env and 'darwin' == sys.platform: | 181 | if 'http_proxy' in env and 'darwin' == sys.platform: |
263 | s = "'http.proxy=%s'" % (env['http_proxy'],) | 182 | s = "'http.proxy=%s'" % (env['http_proxy'],) |
@@ -340,7 +259,7 @@ class GitCommand(object): | |||
340 | raise GitError('%s: %s' % (command[1], e)) | 259 | raise GitError('%s: %s' % (command[1], e)) |
341 | 260 | ||
342 | if ssh_proxy: | 261 | if ssh_proxy: |
343 | _add_ssh_client(p) | 262 | ssh.add_client(p) |
344 | 263 | ||
345 | self.process = p | 264 | self.process = p |
346 | if input: | 265 | if input: |
@@ -352,7 +271,7 @@ class GitCommand(object): | |||
352 | try: | 271 | try: |
353 | self.stdout, self.stderr = p.communicate() | 272 | self.stdout, self.stderr = p.communicate() |
354 | finally: | 273 | finally: |
355 | _remove_ssh_client(p) | 274 | ssh.remove_client(p) |
356 | self.rc = p.wait() | 275 | self.rc = p.wait() |
357 | 276 | ||
358 | @staticmethod | 277 | @staticmethod |