From c438c148dc2e4f9b11368fb16d21db8ef3bdb0f8 Mon Sep 17 00:00:00 2001 From: "tandrii@chromium.org" Date: Mon, 24 Aug 2015 22:55:55 +0000 Subject: [PATCH] Gclient with git cache: delete conflicting mirror. Consider an SVN repo which was mirrored to git by git_updater. When SVN repo is migrated to github, the git histories of chromium mirror and new github one are different. As a result, hashes of the objects do not match. Before, gclient would just get stuck at trying to fetch the repo after changing its remote url with errors like this: ... [0:01:21] error: refs/heads/master does not point to a valid object! [0:01:21] error: refs/remotes/origin/HEAD does not point to a valid object! [0:01:21] error: refs/remotes/origin/master does not point to a valid object! [0:01:21] error: refs/heads/master does not point to a valid object! [0:01:21] error: refs/remotes/origin/HEAD does not point to a valid object! [0:01:21] error: refs/remotes/origin/master does not point to a valid object! [0:01:21] fatal: bad object HEAD [0:01:21] error: /b/git-cache/chromium.googlesource.com-external-github.com-google-open--vcdiff did not send all necessary objects The solution is to notice such state, delete the .git folder, and clone again. BUG=523239 R=akuegel@chromium.org Review URL: https://codereview.chromium.org/1303293002 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@296417 0039d316-1c4b-4281-b951-d872f2087c98 --- gclient_scm.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/gclient_scm.py b/gclient_scm.py index 4e3ab8264..12ef85401 100644 --- a/gclient_scm.py +++ b/gclient_scm.py @@ -461,8 +461,12 @@ class GitWrapper(SCMWrapper): self.checkout_path, '.git', 'objects', 'info', 'alternates'), 'w') as fh: fh.write(os.path.join(url, 'objects')) + self._EnsureValidHeadObjectOrCheckout(revision, options, url) self._FetchAndReset(revision, file_list, options) + return_early = True + else: + self._EnsureValidHeadObjectOrCheckout(revision, options, url) if return_early: return self._Capture(['rev-parse', '--verify', 'HEAD']) @@ -1039,6 +1043,29 @@ class GitWrapper(SCMWrapper): raise gclient_utils.Error('git version %s < minimum required %s' % (current_version, min_version)) + def _EnsureValidHeadObjectOrCheckout(self, revision, options, url): + # Special case handling if all 3 conditions are met: + # * the mirros have recently changed, but deps destination remains same, + # * the git histories of mirrors are conflicting. + # * git cache is used + # This manifests itself in current checkout having invalid HEAD commit on + # most git operations. Since git cache is used, just deleted the .git + # folder, and re-create it by cloning. + try: + self._Capture(['rev-list', '-n', '1', 'HEAD']) + except subprocess2.CalledProcessError as e: + if ('fatal: bad object HEAD' in e.stderr + and self.cache_dir and self.cache_dir in url): + self.Print(( + 'Likely due to DEPS change with git cache_dir, ' + 'the current commit points to no longer existing object.\n' + '%s' % e) + ) + self._DeleteOrMove(options.force) + self._Clone(revision, url, options) + else: + raise + def _IsRebasing(self): # Check for any of REBASE-i/REBASE-m/REBASE/AM. Unfortunately git doesn't # have a plumbing command to determine whether a rebase is in progress, so