diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | cf31fe9b4fb650b27e19f5d7ee7297e383660caf (patch) | |
tree | d04ca6a45d579dca5e5469606c48c405aee68f4b /git_command.py | |
download | git-repo-cf31fe9b4fb650b27e19f5d7ee7297e383660caf.tar.gz |
Initial Contributionv1.0
Diffstat (limited to 'git_command.py')
-rw-r--r-- | git_command.py | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/git_command.py b/git_command.py new file mode 100644 index 00000000..a3bd9192 --- /dev/null +++ b/git_command.py | |||
@@ -0,0 +1,164 @@ | |||
1 | # | ||
2 | # Copyright (C) 2008 The Android Open Source Project | ||
3 | # | ||
4 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | # you may not use this file except in compliance with the License. | ||
6 | # You may obtain a copy of the License at | ||
7 | # | ||
8 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | # | ||
10 | # Unless required by applicable law or agreed to in writing, software | ||
11 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | # See the License for the specific language governing permissions and | ||
14 | # limitations under the License. | ||
15 | |||
16 | import os | ||
17 | import sys | ||
18 | import subprocess | ||
19 | from error import GitError | ||
20 | |||
21 | GIT = 'git' | ||
22 | MIN_GIT_VERSION = (1, 5, 4) | ||
23 | GIT_DIR = 'GIT_DIR' | ||
24 | REPO_TRACE = 'REPO_TRACE' | ||
25 | |||
26 | LAST_GITDIR = None | ||
27 | LAST_CWD = None | ||
28 | try: | ||
29 | TRACE = os.environ[REPO_TRACE] == '1' | ||
30 | except KeyError: | ||
31 | TRACE = False | ||
32 | |||
33 | |||
34 | class _GitCall(object): | ||
35 | def version(self): | ||
36 | p = GitCommand(None, ['--version'], capture_stdout=True) | ||
37 | if p.Wait() == 0: | ||
38 | return p.stdout | ||
39 | return None | ||
40 | |||
41 | def __getattr__(self, name): | ||
42 | name = name.replace('_','-') | ||
43 | def fun(*cmdv): | ||
44 | command = [name] | ||
45 | command.extend(cmdv) | ||
46 | return GitCommand(None, command).Wait() == 0 | ||
47 | return fun | ||
48 | git = _GitCall() | ||
49 | |||
50 | class GitCommand(object): | ||
51 | def __init__(self, | ||
52 | project, | ||
53 | cmdv, | ||
54 | bare = False, | ||
55 | provide_stdin = False, | ||
56 | capture_stdout = False, | ||
57 | capture_stderr = False, | ||
58 | disable_editor = False, | ||
59 | cwd = None, | ||
60 | gitdir = None): | ||
61 | env = dict(os.environ) | ||
62 | |||
63 | for e in [REPO_TRACE, | ||
64 | GIT_DIR, | ||
65 | 'GIT_ALTERNATE_OBJECT_DIRECTORIES', | ||
66 | 'GIT_OBJECT_DIRECTORY', | ||
67 | 'GIT_WORK_TREE', | ||
68 | 'GIT_GRAFT_FILE', | ||
69 | 'GIT_INDEX_FILE']: | ||
70 | if e in env: | ||
71 | del env[e] | ||
72 | |||
73 | if disable_editor: | ||
74 | env['GIT_EDITOR'] = ':' | ||
75 | |||
76 | if project: | ||
77 | if not cwd: | ||
78 | cwd = project.worktree | ||
79 | if not gitdir: | ||
80 | gitdir = project.gitdir | ||
81 | |||
82 | command = [GIT] | ||
83 | if bare: | ||
84 | if gitdir: | ||
85 | env[GIT_DIR] = gitdir | ||
86 | cwd = None | ||
87 | command.extend(cmdv) | ||
88 | |||
89 | if provide_stdin: | ||
90 | stdin = subprocess.PIPE | ||
91 | else: | ||
92 | stdin = None | ||
93 | |||
94 | if capture_stdout: | ||
95 | stdout = subprocess.PIPE | ||
96 | else: | ||
97 | stdout = None | ||
98 | |||
99 | if capture_stderr: | ||
100 | stderr = subprocess.PIPE | ||
101 | else: | ||
102 | stderr = None | ||
103 | |||
104 | if TRACE: | ||
105 | global LAST_CWD | ||
106 | global LAST_GITDIR | ||
107 | |||
108 | dbg = '' | ||
109 | |||
110 | if cwd and LAST_CWD != cwd: | ||
111 | if LAST_GITDIR or LAST_CWD: | ||
112 | dbg += '\n' | ||
113 | dbg += ': cd %s\n' % cwd | ||
114 | LAST_CWD = cwd | ||
115 | |||
116 | if GIT_DIR in env and LAST_GITDIR != env[GIT_DIR]: | ||
117 | if LAST_GITDIR or LAST_CWD: | ||
118 | dbg += '\n' | ||
119 | dbg += ': export GIT_DIR=%s\n' % env[GIT_DIR] | ||
120 | LAST_GITDIR = env[GIT_DIR] | ||
121 | |||
122 | dbg += ': ' | ||
123 | dbg += ' '.join(command) | ||
124 | if stdin == subprocess.PIPE: | ||
125 | dbg += ' 0<|' | ||
126 | if stdout == subprocess.PIPE: | ||
127 | dbg += ' 1>|' | ||
128 | if stderr == subprocess.PIPE: | ||
129 | dbg += ' 2>|' | ||
130 | print >>sys.stderr, dbg | ||
131 | |||
132 | try: | ||
133 | p = subprocess.Popen(command, | ||
134 | cwd = cwd, | ||
135 | env = env, | ||
136 | stdin = stdin, | ||
137 | stdout = stdout, | ||
138 | stderr = stderr) | ||
139 | except Exception, e: | ||
140 | raise GitError('%s: %s' % (command[1], e)) | ||
141 | |||
142 | self.process = p | ||
143 | self.stdin = p.stdin | ||
144 | |||
145 | def Wait(self): | ||
146 | p = self.process | ||
147 | |||
148 | if p.stdin: | ||
149 | p.stdin.close() | ||
150 | self.stdin = None | ||
151 | |||
152 | if p.stdout: | ||
153 | self.stdout = p.stdout.read() | ||
154 | p.stdout.close() | ||
155 | else: | ||
156 | p.stdout = None | ||
157 | |||
158 | if p.stderr: | ||
159 | self.stderr = p.stderr.read() | ||
160 | p.stderr.close() | ||
161 | else: | ||
162 | p.stderr = None | ||
163 | |||
164 | return self.process.wait() | ||