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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | py/utils/git_utils_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: py/utils/git_utils.py
diff --git a/py/utils/git_utils.py b/py/utils/git_utils.py
index 5ac63ec26a8f1ddfd821c876fffd258dd49b3b24..52ad83a6409fd4ff17853e966ba69b68775cdc28 100644
--- a/py/utils/git_utils.py
+++ b/py/utils/git_utils.py
@@ -5,9 +5,12 @@
"""This module contains functions for using git."""
-
+import os
import re
import shell_utils
+import shutil
+import subprocess
+import tempfile
def _FindGit():
@@ -144,3 +147,79 @@ class GitBranch(object):
shell_utils.run([GIT, 'checkout', 'master'])
if self._delete_when_finished:
shell_utils.run([GIT, 'branch', '-D', self._branch_name])
+
+
+class NewGitCheckout(object):
+ """Creates a new local checkout of a Git repository."""
+
+ def __init__(self, repository, refspec=None, subdir=None,
+ 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.
+ """Check out a new local copy of the repository.
+
+ Because this is a new checkout, rather than a reference to an existing
+ checkout on disk, it is safe to assume that the calling thread is the
+ only thread manipulating the checkout.
+
+ You can use the 'with' statement to create this object in such a way that
+ it cleans up after itself:
+
+ with NewGitCheckout(*args) as checkout:
+ # use checkout instance
+ # the checkout is automatically cleaned up here
+
+ Args:
+ repository: name of the remote repository
+ refspec: an arbitrary remote ref (e.g., the name of a branch);
+ if None, allow the git command to pick a default
+ subdir: if specified, the caller only wants access to files within this
+ subdir in the repository.
+ For now, we check out the entire repository regardless of this param,
+ and just hide the rest of the repository; but later on we may
+ optimize performance by only checking out this part of the repo.
+ containing_dir: if specified, the new checkout will be created somewhere
+ within this directory; otherwise, a system-dependent default location
+ will be used, as determined by tempfile.mkdtemp()
+ """
+ # _git_root points to the tree holding the git checkout in its entirety;
+ # _file_root points to the files the caller wants to look at
+ self._git_root = tempfile.mkdtemp(dir=containing_dir)
+ if subdir:
+ self._file_root = os.path.join(self._git_root, subdir)
+ else:
+ self._file_root = self._git_root
+
+ pull_cmd = [GIT, 'pull', repository]
+ if refspec:
+ pull_cmd.append(refspec)
+ self._run_in_git_root(args=[GIT, 'init'])
+ self._run_in_git_root(args=pull_cmd)
+
+ @property
+ def root(self):
+ """Returns the root directory containing the checked-out files.
+
+ If you specified the subdir parameter in the constructor, this directory
+ will point at just the subdir you requested.
+ """
+ return self._file_root
+
+ def commithash(self):
+ """Returns the commithash of the local checkout."""
+ return self._run_in_git_root(
+ args=[GIT, 'rev-parse', 'HEAD']).strip()
+
+ def __enter__(self):
+ return self
+
+ # pylint: disable=W0622
+ def __exit__(self, type, value, traceback):
+ shutil.rmtree(self._git_root)
+
+ def _run_in_git_root(self, args):
+ """Run an external command with cwd set to self._git_root.
+
+ Returns the command's output as a byte string.
+
+ Raises an Exception if the command fails.
+ """
+ return subprocess.check_output(args=args, cwd=self._git_root)
« 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