Browse Source

Merge "Fix permanently broken git cache"

tags/3.4.0
Zuul 5 months ago
parent
commit
300915538c
2 changed files with 17 additions and 1 deletions
  1. 8
    0
      tests/unit/test_merger_repo.py
  2. 9
    1
      zuul/merger/merger.py

+ 8
- 0
tests/unit/test_merger_repo.py View File

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

+ 9
- 1
zuul/merger/merger.py View File

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

Loading…
Cancel
Save