Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1213)

Side by Side Diff: py/utils/git_utils.py

Issue 464413003: add NewGitCheckout to git_utils.py (Closed) Base URL: https://skia.googlesource.com/common.git@master
Patch Set: small documentation-only changes Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | py/utils/git_utils_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2014 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """This module contains functions for using git.""" 6 """This module contains functions for using git."""
7 7
8 8 import os
9 import re 9 import re
10 import shell_utils 10 import shell_utils
11 import shutil
12 import subprocess
13 import tempfile
11 14
12 15
13 def _FindGit(): 16 def _FindGit():
14 """Find the git executable. 17 """Find the git executable.
15 18
16 Returns: 19 Returns:
17 A string suitable for passing to subprocess functions, or None. 20 A string suitable for passing to subprocess functions, or None.
18 """ 21 """
19 def test_git_executable(git): 22 def test_git_executable(git):
20 """Test the git executable. 23 """Test the git executable.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 def __exit__(self, exc_type, _value, _traceback): 140 def __exit__(self, exc_type, _value, _traceback):
138 if self._upload: 141 if self._upload:
139 # Only upload if no error occurred. 142 # Only upload if no error occurred.
140 try: 143 try:
141 if exc_type is None: 144 if exc_type is None:
142 self.commit_and_upload(use_commit_queue=self._commit_queue) 145 self.commit_and_upload(use_commit_queue=self._commit_queue)
143 finally: 146 finally:
144 shell_utils.run([GIT, 'checkout', 'master']) 147 shell_utils.run([GIT, 'checkout', 'master'])
145 if self._delete_when_finished: 148 if self._delete_when_finished:
146 shell_utils.run([GIT, 'branch', '-D', self._branch_name]) 149 shell_utils.run([GIT, 'branch', '-D', self._branch_name])
150
151
152 class NewGitCheckout(object):
153 """Creates a new local checkout of a Git repository."""
154
155 def __init__(self, repository, refspec=None, subdir=None,
156 containing_dir=None):
rmistry 2014/08/13 20:13:20 I think it makes sense to have this default to tem
rmistry 2014/08/13 20:14:20 Ah I just saw your documentation update, so if dir
epoger 2014/08/13 21:03:45 Yup, you got it.
157 """Check out a new local copy of the repository.
158
159 Because this is a new checkout, rather than a reference to an existing
160 checkout on disk, it is safe to assume that the calling thread is the
161 only thread manipulating the checkout.
162
163 You can use the 'with' statement to create this object in such a way that
164 it cleans up after itself:
165
166 with NewGitCheckout(*args) as checkout:
167 # use checkout instance
168 # the checkout is automatically cleaned up here
169
170 Args:
171 repository: name of the remote repository
172 refspec: an arbitrary remote ref (e.g., the name of a branch);
173 if None, allow the git command to pick a default
174 subdir: if specified, the caller only wants access to files within this
175 subdir in the repository.
176 For now, we check out the entire repository regardless of this param,
177 and just hide the rest of the repository; but later on we may
178 optimize performance by only checking out this part of the repo.
179 containing_dir: if specified, the new checkout will be created somewhere
180 within this directory; otherwise, a system-dependent default location
181 will be used, as determined by tempfile.mkdtemp()
182 """
183 # _git_root points to the tree holding the git checkout in its entirety;
184 # _file_root points to the files the caller wants to look at
185 self._git_root = tempfile.mkdtemp(dir=containing_dir)
186 if subdir:
187 self._file_root = os.path.join(self._git_root, subdir)
188 else:
189 self._file_root = self._git_root
190
191 pull_cmd = [GIT, 'pull', repository]
192 if refspec:
193 pull_cmd.append(refspec)
194 self._run_in_git_root(args=[GIT, 'init'])
195 self._run_in_git_root(args=pull_cmd)
196
197 @property
198 def root(self):
199 """Returns the root directory containing the checked-out files.
200
201 If you specified the subdir parameter in the constructor, this directory
202 will point at just the subdir you requested.
203 """
204 return self._file_root
205
206 def commithash(self):
207 """Returns the commithash of the local checkout."""
208 return self._run_in_git_root(
209 args=[GIT, 'rev-parse', 'HEAD']).strip()
210
211 def __enter__(self):
212 return self
213
214 # pylint: disable=W0622
215 def __exit__(self, type, value, traceback):
216 shutil.rmtree(self._git_root)
217
218 def _run_in_git_root(self, args):
219 """Run an external command with cwd set to self._git_root.
220
221 Returns the command's output as a byte string.
222
223 Raises an Exception if the command fails.
224 """
225 return subprocess.check_output(args=args, cwd=self._git_root)
OLDNEW
« no previous file with comments | « no previous file | py/utils/git_utils_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698