CachedRepo: do force checkout when updating working copy
authorMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Wed, 17 Apr 2013 11:50:41 +0000 (14:50 +0300)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Wed, 17 Apr 2013 12:00:09 +0000 (15:00 +0300)
The index of cached repo may be out-of-sync with FETCH_HEAD. In this
case normal checkout fails.

Change-Id: Id2ec2a41bccde49bc4a2622d771517ab95ba7254
Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
obs_service_gbp/__init__.py
tests/test_obs_service_gbp.py

index 396b2f815e71fd5736678ac2b1de104d22252a56..be18f21bc3502d038a314536da0df398d2b2d902 100644 (file)
@@ -57,6 +57,10 @@ class MirrorGitRepository(GitRepository): # pylint: disable=R0904
             with open(os.path.join(self.git_dir, 'FETCH_HEAD'), 'w') as fhead:
                 fhead.write('0000000000000000000000000000000000000000\n')
 
+    def force_checkout(self, commitish):
+        """Checkout commitish"""
+        self._git_command("checkout", ['--force', commitish])
+
     @classmethod
     def clone(cls, path, url, bare=False):
         """Create a mirrored clone"""
@@ -174,7 +178,7 @@ class CachedRepo(object):
         # Resolve commit-ish to sha-1 and set HEAD (and working copy) to it
         try:
             sha = self.repo.rev_parse(commitish)
-            self.repo.set_branch(sha)
+            self.repo.force_checkout(sha)
         except GitRepositoryError as err:
             raise CachedRepoError("Unknown ref '%s': %s" % (commitish, err))
         self.repo.force_head(sha, hard=True)
index e9cca0ed2ee45196dc67f068072b5192a913d2d3..9609cd0b14a9b9f324fd55084557422c0bb5414a 100644 (file)
@@ -222,6 +222,23 @@ class TestCachedRepo(UnitTestsBase):
         with assert_raises(CachedRepoError):
             sha = repo.update_working_copy('foo/bar')
 
+    def test_update_dirty_index(self):
+        """Test situation where index is out-of-sync with HEAD"""
+
+        self.update_repository_file(self.orig_repo, 'foo.txt', 'more data\n')
+        shas = [self.orig_repo.rev_parse('HEAD~2'),
+                self.orig_repo.rev_parse('HEAD~1'),
+                self.orig_repo.rev_parse('HEAD')]
+        repo = CachedRepo(self.orig_repo.path)
+        repo.update_working_copy(shas[-1])
+        del repo
+
+        # Change upstream, after this index cached repo will be out-of-sync
+        # from orig HEAD
+        self.orig_repo.set_branch('HEAD~1')
+        repo = CachedRepo(self.orig_repo.path)
+        assert repo.update_working_copy(shas[0]) == shas[0]
+
     def test_update_bare(self):
         """Test update for bare repository"""
         repo = CachedRepo(self.orig_repo.path, bare=True)