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

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

Issue 484143002: git_utils.py: allow checkouts of local repositories at any commithash along master branch (Closed) Base URL: https://skia.googlesource.com/common.git@master
Patch Set: back to calling "git fetch" for more efficiency in certain situations 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_manualtest.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 import os 8 import os
9 import re 9 import re
10 import shell_utils 10 import shell_utils
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 self.commit_and_upload(use_commit_queue=self._commit_queue) 145 self.commit_and_upload(use_commit_queue=self._commit_queue)
146 finally: 146 finally:
147 shell_utils.run([GIT, 'checkout', 'master']) 147 shell_utils.run([GIT, 'checkout', 'master'])
148 if self._delete_when_finished: 148 if self._delete_when_finished:
149 shell_utils.run([GIT, 'branch', '-D', self._branch_name]) 149 shell_utils.run([GIT, 'branch', '-D', self._branch_name])
150 150
151 151
152 class NewGitCheckout(object): 152 class NewGitCheckout(object):
153 """Creates a new local checkout of a Git repository.""" 153 """Creates a new local checkout of a Git repository."""
154 154
155 def __init__(self, repository, refspec=None, subdir=None, 155 def __init__(self, repository, refspec=None, commit='HEAD',
156 containing_dir=None): 156 subdir=None, containing_dir=None):
157 """Check out a new local copy of the repository. 157 """Set parameters for this local copy of a Git repository.
158 158
159 Because this is a new checkout, rather than a reference to an existing 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 160 checkout on disk, it is safe to assume that the calling thread is the
161 only thread manipulating the checkout. 161 only thread manipulating the checkout.
162 162
163 You can use the 'with' statement to create this object in such a way that 163 You must use the 'with' statement to create this object:
164 it cleans up after itself:
165 164
166 with NewGitCheckout(*args) as checkout: 165 with NewGitCheckout(*args) as checkout:
167 # use checkout instance 166 # use checkout instance
168 # the checkout is automatically cleaned up here 167 # the checkout is automatically cleaned up here
169 168
170 Args: 169 Args:
171 repository: name of the remote repository 170 repository: URL of the remote repository (e.g.,
172 refspec: an arbitrary remote ref (e.g., the name of a branch); 171 'https://skia.googlesource.com/common') or path to a local repository
173 if None, allow the git command to pick a default 172 (e.g., '/path/to/repo/.git') to check out a copy of
173 refspec: which refs (e.g., a branch name) to fetch from the repository;
174 if None, git-fetch will choose the default refs to fetch
175 commit: commit hash, branch, or tag within refspec, indicating what point
176 to update the local checkout to
174 subdir: if specified, the caller only wants access to files within this 177 subdir: if specified, the caller only wants access to files within this
175 subdir in the repository. 178 subdir in the repository.
176 For now, we check out the entire repository regardless of this param, 179 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 180 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. 181 optimize performance by only checking out this part of the repo.
179 containing_dir: if specified, the new checkout will be created somewhere 182 containing_dir: if specified, the new checkout will be created somewhere
180 within this directory; otherwise, a system-dependent default location 183 within this directory; otherwise, a system-dependent default location
181 will be used, as determined by tempfile.mkdtemp() 184 will be used, as determined by tempfile.mkdtemp()
182 """ 185 """
183 # _git_root points to the tree holding the git checkout in its entirety; 186 self._repository = repository
184 # _file_root points to the files the caller wants to look at 187 self._refspec = refspec
185 self._git_root = tempfile.mkdtemp(dir=containing_dir) 188 self._commit = commit
186 if subdir: 189 self._subdir = subdir
187 self._file_root = os.path.join(self._git_root, subdir) 190 self._containing_dir = containing_dir
188 else: 191 self._git_root = None
189 self._file_root = self._git_root 192 self._file_root = None
190 193
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 194
197 @property 195 @property
198 def root(self): 196 def root(self):
199 """Returns the root directory containing the checked-out files. 197 """Returns the root directory containing the checked-out files.
200 198
201 If you specified the subdir parameter in the constructor, this directory 199 If you specified the subdir parameter in the constructor, this directory
202 will point at just the subdir you requested. 200 will point at just the subdir you requested.
203 """ 201 """
204 return self._file_root 202 return self._file_root
205 203
206 def commithash(self): 204 def commithash(self):
207 """Returns the commithash of the local checkout.""" 205 """Returns the commithash of the local checkout."""
208 return self._run_in_git_root( 206 return self._run_in_git_root(
209 args=[GIT, 'rev-parse', 'HEAD']).strip() 207 args=[GIT, 'rev-parse', 'HEAD']).strip()
210 208
211 def __enter__(self): 209 def __enter__(self):
210 """Check out a new local copy of the repository.
211
212 Uses the parameters that were passed into the constructor.
213 """
214 # _git_root points to the tree holding the git checkout in its entirety;
215 # _file_root points to the files the caller wants to look at
216 self._git_root = tempfile.mkdtemp(dir=self._containing_dir)
217 if self._subdir:
218 self._file_root = os.path.join(self._git_root, self._subdir)
219 else:
220 self._file_root = self._git_root
221
222 local_branch_name = 'local'
223 self._run_in_git_root(args=[GIT, 'init'])
224 fetch_cmd = [GIT, 'fetch', self._repository]
225 if self._refspec:
226 fetch_cmd.append(self._refspec)
227 self._run_in_git_root(args=fetch_cmd)
228 self._run_in_git_root(args=[GIT, 'merge', 'FETCH_HEAD'])
229 self._run_in_git_root(args=[GIT, 'branch', local_branch_name, self._commit])
230 self._run_in_git_root(args=[GIT, 'checkout', local_branch_name])
231
212 return self 232 return self
213 233
214 # pylint: disable=W0622 234 # pylint: disable=W0622
215 def __exit__(self, type, value, traceback): 235 def __exit__(self, type, value, traceback):
216 shutil.rmtree(self._git_root) 236 shutil.rmtree(self._git_root)
217 237
218 def _run_in_git_root(self, args): 238 def _run_in_git_root(self, args):
219 """Run an external command with cwd set to self._git_root. 239 """Run an external command with cwd set to self._git_root.
220 240
221 Returns the command's output as a byte string. 241 Returns the command's output as a byte string.
222 242
223 Raises an Exception if the command fails. 243 Raises an Exception if the command fails.
224 """ 244 """
225 return subprocess.check_output(args=args, cwd=self._git_root) 245 return subprocess.check_output(args=args, cwd=self._git_root)
OLDNEW
« no previous file with comments | « no previous file | py/utils/git_utils_manualtest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698