| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #
- # 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.
- import os
- import sys
- import subprocess
- from error import GitError
- from trace import REPO_TRACE, IsTrace, Trace
- GIT = 'git'
- MIN_GIT_VERSION = (1, 5, 4)
- GIT_DIR = 'GIT_DIR'
- LAST_GITDIR = None
- LAST_CWD = None
- class _GitCall(object):
- def version(self):
- p = GitCommand(None, ['--version'], capture_stdout=True)
- if p.Wait() == 0:
- return p.stdout
- return None
- def __getattr__(self, name):
- name = name.replace('_','-')
- def fun(*cmdv):
- command = [name]
- command.extend(cmdv)
- return GitCommand(None, command).Wait() == 0
- return fun
- git = _GitCall()
- class GitCommand(object):
- def __init__(self,
- project,
- cmdv,
- bare = False,
- provide_stdin = False,
- capture_stdout = False,
- capture_stderr = False,
- disable_editor = False,
- cwd = None,
- gitdir = None):
- env = dict(os.environ)
- for e in [REPO_TRACE,
- GIT_DIR,
- 'GIT_ALTERNATE_OBJECT_DIRECTORIES',
- 'GIT_OBJECT_DIRECTORY',
- 'GIT_WORK_TREE',
- 'GIT_GRAFT_FILE',
- 'GIT_INDEX_FILE']:
- if e in env:
- del env[e]
- if disable_editor:
- env['GIT_EDITOR'] = ':'
- if project:
- if not cwd:
- cwd = project.worktree
- if not gitdir:
- gitdir = project.gitdir
- command = [GIT]
- if bare:
- if gitdir:
- env[GIT_DIR] = gitdir
- cwd = None
- command.extend(cmdv)
- if provide_stdin:
- stdin = subprocess.PIPE
- else:
- stdin = None
- if capture_stdout:
- stdout = subprocess.PIPE
- else:
- stdout = None
- if capture_stderr:
- stderr = subprocess.PIPE
- else:
- stderr = None
- if IsTrace():
- global LAST_CWD
- global LAST_GITDIR
- dbg = ''
- 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]
- dbg += ': '
- dbg += ' '.join(command)
- if stdin == subprocess.PIPE:
- dbg += ' 0<|'
- if stdout == subprocess.PIPE:
- dbg += ' 1>|'
- if stderr == subprocess.PIPE:
- dbg += ' 2>|'
- Trace('%s', dbg)
- try:
- p = subprocess.Popen(command,
- cwd = cwd,
- env = env,
- stdin = stdin,
- stdout = stdout,
- stderr = stderr)
- except Exception, e:
- raise GitError('%s: %s' % (command[1], e))
- self.process = p
- self.stdin = p.stdin
- def Wait(self):
- p = self.process
- if p.stdin:
- p.stdin.close()
- self.stdin = None
- if p.stdout:
- self.stdout = p.stdout.read()
- p.stdout.close()
- else:
- p.stdout = None
- if p.stderr:
- self.stderr = p.stderr.read()
- p.stderr.close()
- else:
- p.stderr = None
- return self.process.wait()
|