<s> import os <EOL> import sys <EOL> import subprocess <EOL> import tempfile <EOL> from signal import SIGTERM <EOL> from error import GitError <EOL> from trace import REPO_TRACE , IsTrace , Trace <EOL> GIT = '<STR_LIT>' <EOL> MIN_GIT_VERSION = ( <NUM_LIT:1> , <NUM_LIT:5> , <NUM_LIT:4> ) <EOL> GIT_DIR = '<STR_LIT>' <EOL> LAST_GITDIR = None <EOL> LAST_CWD = None <EOL> _ssh_proxy_path = None <EOL> _ssh_sock_path = None <EOL> _ssh_clients = [ ] <EOL> def ssh_sock ( create = True ) : <EOL> global _ssh_sock_path <EOL> if _ssh_sock_path is None : <EOL> if not create : <EOL> return None <EOL> dir = '<STR_LIT>' <EOL> if not os . path . exists ( dir ) : <EOL> dir = tempfile . gettempdir ( ) <EOL> _ssh_sock_path = os . path . join ( <EOL> tempfile . mkdtemp ( '<STR_LIT>' , '<STR_LIT>' , dir ) , <EOL> '<STR_LIT>' ) <EOL> return _ssh_sock_path <EOL> def _ssh_proxy ( ) : <EOL> global _ssh_proxy_path <EOL> if _ssh_proxy_path is None : <EOL> _ssh_proxy_path = os . path . join ( <EOL> os . path . dirname ( __file__ ) , <EOL> '<STR_LIT>' ) <EOL> return _ssh_proxy_path <EOL> def _add_ssh_client ( p ) : <EOL> _ssh_clients . append ( p ) <EOL> def _remove_ssh_client ( p ) : <EOL> try : <EOL> _ssh_clients . remove ( p ) <EOL> except ValueError : <EOL> pass <EOL> def terminate_ssh_clients ( ) : <EOL> global _ssh_clients <EOL> for p in _ssh_clients : <EOL> try : <EOL> os . kill ( p . pid , SIGTERM ) <EOL> p . wait ( ) <EOL> except OSError : <EOL> pass <EOL> _ssh_clients = [ ] <EOL> _git_version = None <EOL> class _GitCall ( object ) : <EOL> def version ( self ) : <EOL> p = GitCommand ( None , [ '<STR_LIT>' ] , capture_stdout = True ) <EOL> if p . Wait ( ) == <NUM_LIT:0> : <EOL> return p . stdout <EOL> return None <EOL> def version_tuple ( self ) : <EOL> global _git_version <EOL> if _git_version is None : <EOL> ver_str = git . version ( ) <EOL> if ver_str . startswith ( '<STR_LIT>' ) : <EOL> _git_version = tuple ( <EOL> map ( lambda x : int ( x ) , <EOL> ver_str [ len ( '<STR_LIT>' ) : ] . strip ( ) . split ( '<STR_LIT:.>' ) [ <NUM_LIT:0> : <NUM_LIT:3> ] <EOL> ) ) <EOL> else : <EOL> print >> sys . stderr , '<STR_LIT>' % ver_str <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> return _git_version <EOL> def __getattr__ ( self , name ) : <EOL> name = name . replace ( '<STR_LIT:_>' , '<STR_LIT:->' ) <EOL> def fun ( * cmdv ) : <EOL> command = [ name ] <EOL> command . extend ( cmdv ) <EOL> return GitCommand ( None , command ) . Wait ( ) == <NUM_LIT:0> <EOL> return fun <EOL> git = _GitCall ( ) <EOL> def git_require ( min_version , fail = False ) : <EOL> git_version = git . version_tuple ( ) <EOL> if min_version <= git_version : <EOL> return True <EOL> if fail : <EOL> need = '<STR_LIT:.>' . join ( map ( lambda x : str ( x ) , min_version ) ) <EOL> print >> sys . stderr , '<STR_LIT>' % need <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> return False <EOL> def _setenv ( env , name , value ) : <EOL> env [ name ] = value . encode ( ) <EOL> class GitCommand ( object ) : <EOL> def __init__ ( self , <EOL> project , <EOL> cmdv , <EOL> bare = False , <EOL> provide_stdin = False , <EOL> capture_stdout = False , <EOL> capture_stderr = False , <EOL> disable_editor = False , <EOL> ssh_proxy = False , <EOL> cwd = None , <EOL> gitdir = None ) : <EOL> env = os . environ . copy ( ) <EOL> for e in [ REPO_TRACE , <EOL> GIT_DIR , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' ] : <EOL> if e in env : <EOL> del env [ e ] <EOL> if disable_editor : <EOL> _setenv ( env , '<STR_LIT>' , '<STR_LIT::>' ) <EOL> if ssh_proxy : <EOL> _setenv ( env , '<STR_LIT>' , ssh_sock ( ) ) <EOL> _setenv ( env , '<STR_LIT>' , _ssh_proxy ( ) ) <EOL> if project : <EOL> if not cwd : <EOL> cwd = project . worktree <EOL> if not gitdir : <EOL> gitdir = project . gitdir <EOL> command = [ GIT ] <EOL> if bare : <EOL> if gitdir : <EOL> _setenv ( env , GIT_DIR , gitdir ) <EOL> cwd = None <EOL> command . extend ( cmdv ) <EOL> if provide_stdin : <EOL> stdin = subprocess . PIPE <EOL> else : <EOL> stdin = None <EOL> if capture_stdout : <EOL> stdout = subprocess . PIPE <EOL> else : <EOL> stdout = None <EOL> if capture_stderr : <EOL> stderr = subprocess . PIPE <EOL> else : <EOL> stderr = None <EOL> if IsTrace ( ) : <EOL> global LAST_CWD <EOL> global LAST_GITDIR <EOL> dbg = '<STR_LIT>' <EOL> if cwd and LAST_CWD != cwd : <EOL> if LAST_GITDIR or LAST_CWD : <EOL> dbg += '<STR_LIT:\n>' <EOL> dbg += '<STR_LIT>' % cwd <EOL> LAST_CWD = cwd <EOL> if GIT_DIR in env and LAST_GITDIR != env [ GIT_DIR ] : <EOL> if LAST_GITDIR or LAST_CWD : <EOL> dbg += '<STR_LIT:\n>' <EOL> dbg += '<STR_LIT>' % env [ GIT_DIR ] <EOL> LAST_GITDIR = env [ GIT_DIR ] <EOL> dbg += '<STR_LIT>' <EOL> dbg += '<STR_LIT:U+0020>' . join ( command ) <EOL> if stdin == subprocess . PIPE : <EOL> dbg += '<STR_LIT>' <EOL> if stdout == subprocess . PIPE : <EOL> dbg += '<STR_LIT>' <EOL> if stderr == subprocess . PIPE : <EOL> dbg += '<STR_LIT>' <EOL> Trace ( '<STR_LIT:%s>' , dbg ) <EOL> try : <EOL> p = subprocess . Popen ( command , <EOL> cwd = cwd , <EOL> env = env , <EOL> stdin = stdin , <EOL> stdout = stdout , <EOL> stderr = stderr ) <EOL> except Exception , e : <EOL> raise GitError ( '<STR_LIT>' % ( command [ <NUM_LIT:1> ] , e ) ) <EOL> if ssh_proxy : <EOL> _add_ssh_client ( p ) <EOL> self . process = p <EOL> self . stdin = p . stdin <EOL> def Wait ( self ) : <EOL> p = self . process <EOL> if p . stdin : <EOL> p . stdin . close ( ) <EOL> self . stdin = None <EOL> if p . stdout : <EOL> self . stdout = p . stdout . read ( ) <EOL> p . stdout . close ( ) <EOL> else : <EOL> p . stdout = None <EOL> if p . stderr : <EOL> self . stderr = p . stderr . read ( ) <EOL> p . stderr . close ( ) <EOL> else : <EOL> p . stderr = None <EOL> try : <EOL> rc = p . wait ( ) <EOL> finally : <EOL> _remove_ssh_client ( p ) <EOL> return rc </s>
