Merge "Fix permanently broken git cache"

This commit is contained in:
Zuul 2018-12-01 13:20:21 +00:00 committed by Gerrit Code Review
commit 300915538c
2 changed files with 17 additions and 1 deletions

View File

@ -179,6 +179,14 @@ class TestMergerRepo(ZuulTestCase):
# And now reset the repo again. This should not crash # And now reset the repo again. This should not crash
work_repo.reset() work_repo.reset()
# Now open a cache repo and break it in a way that git.Repo is happy
# at first but git won't be.
merger = self.executor_server.merger
cache_repo = merger.getRepo('gerrit', 'org/project')
with open(os.path.join(cache_repo.local_path, '.git/HEAD'), 'w'):
pass
cache_repo.update()
def test_broken_gitmodules(self): def test_broken_gitmodules(self):
parent_path = os.path.join(self.upstream_root, 'org/project1') parent_path = os.path.join(self.upstream_root, 'org/project1')
work_repo = Repo(parent_path, self.workspace_root, work_repo = Repo(parent_path, self.workspace_root,

View File

@ -212,13 +212,21 @@ class Repo(object):
break break
except Exception as e: except Exception as e:
if attempt < self.retry_attempts: if attempt < self.retry_attempts:
if 'fatal: bad config' in e.stderr: if 'fatal: bad config' in e.stderr.lower():
# This error can be introduced by a merge conflict # This error can be introduced by a merge conflict
# in the .gitmodules which was left by the last # in the .gitmodules which was left by the last
# merge operation. In this case reset and clean # merge operation. In this case reset and clean
# the repo and try again immediately. # the repo and try again immediately.
reset_repo_to_head(repo) reset_repo_to_head(repo)
repo.git.clean('-x', '-f', '-d') repo.git.clean('-x', '-f', '-d')
elif 'fatal: not a git repository' in e.stderr.lower():
# If we get here the git.Repo object was happy with its
# lightweight way of checking if this is a valid git
# repository. However if e.g. the .git/HEAD file is
# empty git operations fail. So there is something
# fundamentally broken with the repo and we need to
# delete it before advancing to _ensure_cloned.
shutil.rmtree(self.local_path)
else: else:
time.sleep(self.retry_interval) time.sleep(self.retry_interval)
self.log.exception("Retry %s: Fetch %s %s %s" % ( self.log.exception("Retry %s: Fetch %s %s %s" % (