diff options
Diffstat (limited to 'git_config.py')
-rw-r--r-- | git_config.py | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/git_config.py b/git_config.py index 1382d5db..138470c5 100644 --- a/git_config.py +++ b/git_config.py | |||
@@ -356,18 +356,21 @@ class RefSpec(object): | |||
356 | return s | 356 | return s |
357 | 357 | ||
358 | 358 | ||
359 | _ssh_cache = {} | 359 | _master_processes = [] |
360 | _master_keys = set() | ||
360 | _ssh_master = True | 361 | _ssh_master = True |
361 | 362 | ||
362 | def _open_ssh(host, port=None): | 363 | def _open_ssh(host, port=None): |
363 | global _ssh_master | 364 | global _ssh_master |
364 | 365 | ||
366 | # Check to see whether we already think that the master is running; if we | ||
367 | # think it's already running, return right away. | ||
365 | if port is not None: | 368 | if port is not None: |
366 | key = '%s:%s' % (host, port) | 369 | key = '%s:%s' % (host, port) |
367 | else: | 370 | else: |
368 | key = host | 371 | key = host |
369 | 372 | ||
370 | if key in _ssh_cache: | 373 | if key in _master_keys: |
371 | return True | 374 | return True |
372 | 375 | ||
373 | if not _ssh_master \ | 376 | if not _ssh_master \ |
@@ -377,15 +380,39 @@ def _open_ssh(host, port=None): | |||
377 | # | 380 | # |
378 | return False | 381 | return False |
379 | 382 | ||
380 | command = ['ssh', | 383 | # We will make two calls to ssh; this is the common part of both calls. |
381 | '-o','ControlPath %s' % ssh_sock(), | 384 | command_base = ['ssh', |
382 | '-M', | 385 | '-o','ControlPath %s' % ssh_sock(), |
383 | '-N', | 386 | host] |
384 | host] | ||
385 | |||
386 | if port is not None: | 387 | if port is not None: |
387 | command[3:3] = ['-p',str(port)] | 388 | command_base[1:1] = ['-p',str(port)] |
388 | 389 | ||
390 | # Since the key wasn't in _master_keys, we think that master isn't running. | ||
391 | # ...but before actually starting a master, we'll double-check. This can | ||
392 | # be important because we can't tell that that 'git@myhost.com' is the same | ||
393 | # as 'myhost.com' where "User git" is setup in the user's ~/.ssh/config file. | ||
394 | check_command = command_base + ['-O','check'] | ||
395 | try: | ||
396 | Trace(': %s', ' '.join(check_command)) | ||
397 | check_process = subprocess.Popen(check_command, | ||
398 | stdout=subprocess.PIPE, | ||
399 | stderr=subprocess.PIPE) | ||
400 | check_process.communicate() # read output, but ignore it... | ||
401 | isnt_running = check_process.wait() | ||
402 | |||
403 | if not isnt_running: | ||
404 | # Our double-check found that the master _was_ infact running. Add to | ||
405 | # the list of keys. | ||
406 | _master_keys.add(key) | ||
407 | return True | ||
408 | except Exception: | ||
409 | # Ignore excpetions. We we will fall back to the normal command and print | ||
410 | # to the log there. | ||
411 | pass | ||
412 | |||
413 | command = command_base[:1] + \ | ||
414 | ['-M', '-N'] + \ | ||
415 | command_base[1:] | ||
389 | try: | 416 | try: |
390 | Trace(': %s', ' '.join(command)) | 417 | Trace(': %s', ' '.join(command)) |
391 | p = subprocess.Popen(command) | 418 | p = subprocess.Popen(command) |
@@ -396,20 +423,22 @@ def _open_ssh(host, port=None): | |||
396 | % (host,port, str(e)) | 423 | % (host,port, str(e)) |
397 | return False | 424 | return False |
398 | 425 | ||
399 | _ssh_cache[key] = p | 426 | _master_processes.append(p) |
427 | _master_keys.add(key) | ||
400 | time.sleep(1) | 428 | time.sleep(1) |
401 | return True | 429 | return True |
402 | 430 | ||
403 | def close_ssh(): | 431 | def close_ssh(): |
404 | terminate_ssh_clients() | 432 | terminate_ssh_clients() |
405 | 433 | ||
406 | for key,p in _ssh_cache.iteritems(): | 434 | for p in _master_processes: |
407 | try: | 435 | try: |
408 | os.kill(p.pid, SIGTERM) | 436 | os.kill(p.pid, SIGTERM) |
409 | p.wait() | 437 | p.wait() |
410 | except OSError: | 438 | except OSError: |
411 | pass | 439 | pass |
412 | _ssh_cache.clear() | 440 | del _master_processes[:] |
441 | _master_keys.clear() | ||
413 | 442 | ||
414 | d = ssh_sock(create=False) | 443 | d = ssh_sock(create=False) |
415 | if d: | 444 | if d: |