| Index: gclient_scm.py
|
| diff --git a/gclient_scm.py b/gclient_scm.py
|
| index e7147ce4058cc13b6d577d13283043bbf1defbfa..af74b754d187d37ae87d7c26c1b0cff4c670cd81 100644
|
| --- a/gclient_scm.py
|
| +++ b/gclient_scm.py
|
| @@ -10,6 +10,7 @@ import os
|
| import posixpath
|
| import re
|
| import sys
|
| +import tempfile
|
| import threading
|
| import time
|
|
|
| @@ -350,10 +351,9 @@ class GitWrapper(SCMWrapper):
|
| # hash is also a tag, only make a distinction at checkout
|
| rev_type = "hash"
|
|
|
| - if not os.path.exists(self.checkout_path) or (
|
| - os.path.isdir(self.checkout_path) and
|
| - not os.listdir(self.checkout_path)):
|
| - gclient_utils.safe_makedirs(os.path.dirname(self.checkout_path))
|
| + if (not os.path.exists(self.checkout_path) or
|
| + (os.path.isdir(self.checkout_path) and
|
| + not os.path.exists(os.path.join(self.checkout_path, '.git')))):
|
| self._Clone(revision, url, options)
|
| self.UpdateSubmoduleConfig()
|
| if file_list is not None:
|
| @@ -408,19 +408,6 @@ class GitWrapper(SCMWrapper):
|
| if return_early:
|
| return
|
|
|
| - if not self._IsValidGitRepo():
|
| - # .git directory is hosed for some reason, set it back up.
|
| - print('_____ %s/.git is corrupted, rebuilding' % self.relpath)
|
| - self._Run(['init'], options)
|
| - self._Run(['remote', 'set-url', 'origin', url], options)
|
| -
|
| - if not self._HasHead():
|
| - # Previous checkout was aborted before branches could be created in repo,
|
| - # so we need to reconstruct them here.
|
| - self._Run(['-c', 'core.deltaBaseCacheLimit=2g', 'pull', 'origin',
|
| - 'master'], options)
|
| - self._FetchAndReset(revision, file_list, options)
|
| -
|
| cur_branch = self._GetCurrentBranch()
|
|
|
| # Cases:
|
| @@ -859,47 +846,45 @@ class GitWrapper(SCMWrapper):
|
| print('')
|
| template_path = os.path.join(
|
| os.path.dirname(THIS_FILE_PATH), 'git-templates')
|
| - clone_cmd = ['-c', 'core.deltaBaseCacheLimit=2g', 'clone', '--progress',
|
| - '--template=%s' % template_path]
|
| + clone_cmd = ['-c', 'core.deltaBaseCacheLimit=2g', 'clone', '--no-checkout',
|
| + '--progress', '--template=%s' % template_path]
|
| if self.cache_dir:
|
| clone_cmd.append('--shared')
|
| - if revision.startswith('refs/heads/'):
|
| - clone_cmd.extend(['-b', revision.replace('refs/heads/', '')])
|
| - detach_head = False
|
| - else:
|
| - detach_head = True
|
| if options.verbose:
|
| clone_cmd.append('--verbose')
|
| - clone_cmd.extend([url, self.checkout_path])
|
| -
|
| + clone_cmd.append(url)
|
| # If the parent directory does not exist, Git clone on Windows will not
|
| # create it, so we need to do it manually.
|
| parent_dir = os.path.dirname(self.checkout_path)
|
| - if not os.path.exists(parent_dir):
|
| - gclient_utils.safe_makedirs(parent_dir)
|
| -
|
| - for _ in range(3):
|
| - try:
|
| - self._Run(clone_cmd, options, cwd=self._root_dir, git_filter=True)
|
| - break
|
| - except subprocess2.CalledProcessError, e:
|
| - # Too bad we don't have access to the actual output yet.
|
| - # We should check for "transfer closed with NNN bytes remaining to
|
| - # read". In the meantime, just make sure .git exists.
|
| - if (e.returncode == 128 and
|
| - os.path.exists(os.path.join(self.checkout_path, '.git'))):
|
| + gclient_utils.safe_makedirs(parent_dir)
|
| + tmp_dir = tempfile.mkdtemp(
|
| + prefix='_gclient_%s_' % os.path.basename(self.checkout_path),
|
| + dir=parent_dir)
|
| + try:
|
| + clone_cmd.append(tmp_dir)
|
| + for i in xrange(3):
|
| + try:
|
| + self._Run(clone_cmd, options, cwd=self._root_dir, git_filter=True)
|
| + break
|
| + except subprocess2.CalledProcessError as e:
|
| + gclient_utils.rmtree(os.path.join(tmp_dir, '.git'))
|
| + if e.returncode != 128 or i == 2:
|
| + raise
|
| print(str(e))
|
| print('Retrying...')
|
| - continue
|
| - raise e
|
| -
|
| - # Update the "branch-heads" remote-tracking branches, since we might need it
|
| - # to checkout a specific revision below.
|
| - self._UpdateBranchHeads(options, fetch=True)
|
| -
|
| - if detach_head:
|
| + gclient_utils.safe_makedirs(self.checkout_path)
|
| + os.rename(os.path.join(tmp_dir, '.git'),
|
| + os.path.join(self.checkout_path, '.git'))
|
| + finally:
|
| + if os.listdir(tmp_dir):
|
| + print('\n_____ removing non-empty tmp dir %s' % tmp_dir)
|
| + gclient_utils.rmtree(tmp_dir)
|
| + if revision.startswith('refs/heads/'):
|
| + self._Run(
|
| + ['checkout', '--quiet', revision.replace('refs/heads/', '')], options)
|
| + else:
|
| # Squelch git's very verbose detached HEAD warning and use our own
|
| - self._Capture(['checkout', '--quiet', '%s' % revision])
|
| + self._Run(['checkout', '--quiet', revision], options)
|
| print(
|
| ('Checked out %s to a detached HEAD. Before making any commits\n'
|
| 'in this repo, you should use \'git checkout <branch>\' to switch to\n'
|
| @@ -977,28 +962,6 @@ class GitWrapper(SCMWrapper):
|
| # whitespace between projects when syncing.
|
| print('')
|
|
|
| - def _IsValidGitRepo(self):
|
| - """Returns if the directory is a valid git repository.
|
| -
|
| - Checks if git status works.
|
| - """
|
| - try:
|
| - self._Capture(['status'])
|
| - return True
|
| - except subprocess2.CalledProcessError:
|
| - return False
|
| -
|
| - def _HasHead(self):
|
| - """Returns True if any commit is checked out.
|
| -
|
| - This is done by checking if rev-parse HEAD works in the current repository.
|
| - """
|
| - try:
|
| - self._GetCurrentBranch()
|
| - return True
|
| - except subprocess2.CalledProcessError:
|
| - return False
|
| -
|
| @staticmethod
|
| def _CheckMinVersion(min_version):
|
| (ok, current_version) = scm.GIT.AssertVersion(min_version)
|
|
|