From c376171c1b858fabb0c50fab475ca23f95da5a8a Mon Sep 17 00:00:00 2001 From: "xusydoc@chromium.org" Date: Wed, 12 Jun 2013 00:53:36 +0000 Subject: [PATCH] Repair broken git checkouts caused by aborting git clone. BUG=248384 Review URL: https://chromiumcodereview.appspot.com/16763004 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@205692 0039d316-1c4b-4281-b951-d872f2087c98 --- gclient_scm.py | 56 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/gclient_scm.py b/gclient_scm.py index 01dfd5467..2cdee7df8 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']) + 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)