From: Markus Lehtonen Date: Wed, 5 Mar 2014 12:04:57 +0000 (+0200) Subject: MirrorGitRepository: fix git-fetch failure when local HEAD is invalid X-Git-Tag: submit/devel/20190730.075437~55 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=be338310550cf9ae329e6fd7853d11a479bec7f1;p=services%2Fobs-service-git-buildpackage.git MirrorGitRepository: fix git-fetch failure when local HEAD is invalid Git fetch fails if local HEAD is a non-symbolic ref and points to a non-existent object. We get into this state in CachedRepo if the remote HEAD is invalid (e.g. points to a non-existent branch) as we forcefully invalidate local HEAD in this case, too. Change-Id: I68dff3b4692bef0c3b5399f06c7097af1cf104b3 Signed-off-by: Markus Lehtonen --- diff --git a/gbp_repocache/__init__.py b/gbp_repocache/__init__.py index ade3e89..d1e009e 100644 --- a/gbp_repocache/__init__.py +++ b/gbp_repocache/__init__.py @@ -68,15 +68,22 @@ class MirrorGitRepository(GitRepository): # pylint: disable=R0904 def force_fetch(self): """Fetch with specific arguments""" + # Set HEAD temporarily as fetch with an invalid non-symbolic HEAD fails + orig_head = self.get_ref('HEAD') + self.set_ref('HEAD', 'refs/heads/non-existent-tmp-for-fetching') + # Update all refs - self._git_command('fetch', ['-q', '-u', '-p', 'origin']) try: - # Fetch remote HEAD separately - self._git_command('fetch', ['-q', '-u', 'origin', 'HEAD']) - except GitRepositoryError: - # If remote HEAD is invalid, invalidate FETCH_HEAD, too - self.set_ref('FETCH_HEAD', - '0000000000000000000000000000000000000000') + self._git_command('fetch', ['-q', '-u', '-p', 'origin']) + try: + # Fetch remote HEAD separately + self._git_command('fetch', ['-q', '-u', 'origin', 'HEAD']) + except GitRepositoryError: + # If remote HEAD is invalid, invalidate FETCH_HEAD, too + self.set_ref('FETCH_HEAD', + '0000000000000000000000000000000000000000') + finally: + self.set_ref('HEAD', orig_head) def force_checkout(self, commitish): """Checkout commitish""" diff --git a/tests/test_gbp_repocache.py b/tests/test_gbp_repocache.py index 83a1342..aa68391 100644 --- a/tests/test_gbp_repocache.py +++ b/tests/test_gbp_repocache.py @@ -57,6 +57,28 @@ class TestMirrorGitRepository(UnitTestsBase): repo.set_ref('MY_REF', sha1) eq_(repo.get_ref('MY_REF'), sha1) + def test_force_fetch(self): + """Test fetching""" + repo = MirrorGitRepository.clone('testrepo', self.orig_repo.path) + + # Make remote HEAD invalid + orig_branch = self.orig_repo.get_branch() + with open(os.path.join(self.orig_repo.git_dir, 'HEAD'), 'w') as head: + head.write('ref: refs/heads/non-existent-branch\n') + + # Local HEAD should be invalid after fetch + repo.force_fetch() + eq_(repo.get_ref('FETCH_HEAD'), + '0000000000000000000000000000000000000000') + + # Fetch should succeed even if local head is invalid + repo.set_ref('HEAD', '1234567890123456789012345678901234567890') + repo.force_fetch() + eq_(repo.get_ref('HEAD'), '1234567890123456789012345678901234567890') + + # Restore orig repo HEAD + self.orig_repo.set_branch(orig_branch) + class TestCachedRepo(UnitTestsBase): """Test CachedRepo class""" @@ -163,6 +185,11 @@ class TestCachedRepo(UnitTestsBase): # Local HEAD should be invalid, now with assert_raises(CachedRepoError): repo.update_working_copy('HEAD') + repo.close() + + # Init/fetch with invalid local HEAD should succeed + repo = self.MockCachedRepo(self.orig_repo.path) + # Test valid refs, too ok_(repo.update_working_copy('master'))