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

Unified Diff: gclient_scm.py

Issue 235005: gclient_scm: add support for .git (Closed)
Patch Set: Fixed per code review. Created 11 years, 3 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 | « PRESUBMIT.py ('k') | tests/gclient_scm_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gclient_scm.py
diff --git a/gclient_scm.py b/gclient_scm.py
index fe0ac9839794dd5651f6d985340c65f2c464247c..78118ec1f265185ae3f6ea77b4038ceb33e10eb7 100644
--- a/gclient_scm.py
+++ b/gclient_scm.py
@@ -34,7 +34,14 @@ def CreateSCM(url=None, root_dir=None, relpath=None, scm_name='svn'):
# TODO(maruel): Deduce the SCM from the url.
scm_map = {
'svn' : SVNWrapper,
+ 'git' : GitWrapper,
}
+
+ if url and (url.startswith('git:') or
+ url.startswith('ssh:') or
+ url.endswith('.git')):
+ scm_name = 'git'
+
if not scm_name in scm_map:
raise gclient_utils.Error('Unsupported scm %s' % scm_name)
return scm_map[scm_name](url, root_dir, relpath, scm_name)
@@ -58,6 +65,8 @@ class SCMWrapper(object):
self.relpath = relpath
if self.relpath:
self.relpath = self.relpath.replace('/', os.sep)
+ if self.relpath and self._root_dir:
+ self.checkout_path = os.path.join(self._root_dir, self.relpath)
def FullUrlForRelativeUrl(self, url):
# Find the forth '/' and strip from there. A bit hackish.
@@ -81,6 +90,99 @@ class SCMWrapper(object):
return getattr(self, command)(options, args, file_list)
+class GitWrapper(SCMWrapper):
+ """Wrapper for Git"""
+
+ def cleanup(self, options, args, file_list):
+ """Cleanup working copy."""
+ self._RunGit(['prune'])
+ self._RunGit(['fsck'])
+ self._RunGit(['gc'])
+
+ def diff(self, options, args, file_list):
+ # NOTE: This function does not currently modify file_list.
+ merge_base = self._RunGit(['merge-base', 'HEAD', 'origin'])
+ print self._RunGit(['diff', merge_base])
+
+ def export(self, options, args, file_list):
+ assert len(args) == 1
+ export_path = os.path.abspath(os.path.join(args[0], self.relpath))
+ if not os.path.exists(export_path):
+ os.makedirs(export_path)
+ self._RunGit(['checkout-index', '-a', '--prefix=%s/' % export_path])
+
+ def update(self, options, args, file_list):
+ """Runs git to update or transparently checkout the working copy.
+
+ All updated files will be appended to file_list.
+
+ Raises:
+ Error: if can't get URL for relative path.
+ """
+
+ if args:
+ raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))
+
+ components = self.url.split("@")
+ url = components[0]
+ revision = None
+ if options.revision:
+ revision = options.revision
+ elif len(components) == 2:
+ revision = components[1]
+
+ if not os.path.exists(self.checkout_path):
+ self._RunGit(['clone', '-q', url, self.checkout_path], cwd=self._root_dir)
+ if revision:
+ self._RunGit(['reset', '--hard', revision])
+ files = self._RunGit(['ls-files']).split()
+ file_list.extend([os.path.join(self.checkout_path, f) for f in files])
+ return
+
+ self._RunGit(['remote', 'update'])
+ new_base = 'origin'
+ if revision:
+ new_base = revision
+ files = self._RunGit(['diff', new_base, '--name-only']).split()
+ file_list.extend([os.path.join(self.checkout_path, f) for f in files])
+ self._RunGit(['rebase', new_base])
+
+ def revert(self, options, args, file_list):
+ """Reverts local modifications.
+
+ All reverted files will be appended to file_list.
+ """
+ merge_base = self._RunGit(['merge-base', 'HEAD', 'origin'])
+ files = self._RunGit(['diff', merge_base, '--name-only']).split()
+ print self._RunGit(['reset', '--hard', merge_base])
+ file_list.extend([os.path.join(self.checkout_path, f) for f in files])
+
+ def runhooks(self, options, args, file_list):
+ self.status(options, args, file_list)
+
+ def status(self, options, args, file_list):
+ """Display status information."""
+ if not os.path.isdir(self.checkout_path):
+ print('\n________ couldn\'t run status in %s:\nThe directory '
+ 'does not exist.' % checkout_path)
+ else:
+ merge_base = self._RunGit(['merge-base', 'HEAD', 'origin'])
+ print self._RunGit(['diff', '--name-status', merge_base])
+ files = self._RunGit(['diff', '--name-only', merge_base]).split()
+ file_list.extend([os.path.join(self.checkout_path, f) for f in files])
+
+ def _RunGit(self, args, cwd=None, checkrc=True):
+ if cwd == None:
+ cwd = self.checkout_path
+ cmd = ['git']
+ cmd.extend(args)
+ sp = subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE)
+ if checkrc and sp.returncode:
+ raise gclient_utils.Error('git command %s returned %d' %
+ (args[0], sp.returncode))
+ return sp.communicate()[0].strip()
+
+
class SVNWrapper(SCMWrapper):
""" Wrapper for SVN """
« no previous file with comments | « PRESUBMIT.py ('k') | tests/gclient_scm_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698