Chromium Code Reviews| Index: gclient_scm.py | 
| diff --git a/gclient_scm.py b/gclient_scm.py | 
| index 01dfd54675b32151d38eb6fe27629650397a32bd..2cdee7df8a1d7823678c9b19048890fe5c04f2c6 100644 | 
| --- a/gclient_scm.py | 
| +++ b/gclient_scm.py | 
| @@ -237,6 +237,18 @@ class GitWrapper(SCMWrapper): | 
| gclient_utils.CheckCallAndFilter(cmd4, **kwargs) | 
| + def _FetchAndReset(self, revision, file_list, options): | 
| + """Equivalent to git fetch; git reset.""" | 
| + quiet = [] | 
| + if not options.verbose: | 
| + quiet = ['--quiet'] | 
| + self._UpdateBranchHeads(options, fetch=False) | 
| + self._Run(['fetch', 'origin', '--prune'] + quiet, options) | 
| + self._Run(['reset', '--hard', revision] + quiet, options) | 
| + self.UpdateSubmoduleConfig() | 
| + files = self._Capture(['ls-files']).splitlines() | 
| + file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 
| + | 
| def update(self, options, args, file_list): | 
| """Runs git to update or transparently checkout the working copy. | 
| @@ -338,17 +350,21 @@ class GitWrapper(SCMWrapper): | 
| self._CheckClean(rev_str) | 
| # Switch over to the new upstream | 
| self._Run(['remote', 'set-url', 'origin', url], options) | 
| - quiet = [] | 
| - if not options.verbose: | 
| - quiet = ['--quiet'] | 
| - self._UpdateBranchHeads(options, fetch=False) | 
| - self._Run(['fetch', 'origin', '--prune'] + quiet, options) | 
| - self._Run(['reset', '--hard', revision] + quiet, options) | 
| - self.UpdateSubmoduleConfig() | 
| - files = self._Capture(['ls-files']).splitlines() | 
| - file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 
| + self._FetchAndReset(revision, file_list, options) | 
| 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(['pull', 'origin', 'master'], options) | 
| + self._FetchAndReset(revision, file_list, options) | 
| + | 
| cur_branch = self._GetCurrentBranch() | 
| # Cases: | 
| @@ -801,6 +817,28 @@ 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']) | 
| 
 
Isaac (away)
2013/07/16 10:06:21
status is a expensive command on some projects (li
 
 | 
| + 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) |