def test_repo_reset_branch_conflict(self): """Test correct reset with conflicting branch names""" parent_path = os.path.join(self.upstream_root, 'org/project1') parent_repo = git.Repo(parent_path) parent_repo.create_head("foobar") work_repo = Repo(parent_path, self.workspace_root, '*****@*****.**', 'User Name', '0', '0') # Checkout branch that will be deleted from the remote repo work_repo.checkout("foobar") # Delete remote branch and create a branch that conflicts with # the branch checked out locally. parent_repo.delete_head("foobar") parent_repo.create_head("foobar/sub") work_repo.reset() work_repo.checkout("foobar/sub") # Try the reverse conflict parent_path = os.path.join(self.upstream_root, 'org/project2') parent_repo = git.Repo(parent_path) parent_repo.create_head("foobar/sub") work_repo = Repo(parent_path, self.workspace_root, '*****@*****.**', 'User Name', '0', '0') # Checkout branch that will be deleted from the remote repo work_repo.checkout("foobar/sub") # Delete remote branch and create a branch that conflicts with # the branch checked out locally. parent_repo.delete_head("foobar/sub") # Note: Before git 2.13 deleting a a ref foo/bar leaves an empty # directory foo behind that will block creating the reference foo # in the future. As a workaround we must clean up empty directories # in .git/refs. if parent_repo.git.version_info[:2] < (2, 13): Repo._cleanup_leaked_ref_dirs(parent_path, None, []) parent_repo.create_head("foobar") work_repo.reset() work_repo.checkout("foobar")
def test_merge_temp_refs(self): """ Test that the merge updates local zuul refs in order to avoid garbage collection of needed objects. """ merger = self.executor_server.merger parent_path = os.path.join(self.upstream_root, 'org/project') parent_repo = git.Repo(parent_path) parent_repo.create_head("foo/bar") # Simple change A A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A') item_a = self._item_from_fake_change(A) # Simple change B on branch foo/bar B = self.fake_gerrit.addFakeChange('org/project', 'foo/bar', 'B') item_b = self._item_from_fake_change(B) # Simple change C C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C') item_c = self._item_from_fake_change(C) # Merge A -> B -> C result = merger.mergeChanges([item_a, item_b, item_c]) self.assertIsNotNone(result) merge_state = result[3] cache_repo = merger.getRepo('gerrit', 'org/project') repo = cache_repo.createRepoObject(zuul_event_id="dummy") # Make sure zuul refs are updated foobar_zuul_ref = Repo.refNameToZuulRef("foo/bar") master_zuul_ref = Repo.refNameToZuulRef("master") ref_map = {r.path: r for r in repo.refs} self.assertIn(foobar_zuul_ref, ref_map) self.assertIn(master_zuul_ref, ref_map) self.assertEqual(ref_map[master_zuul_ref].commit.hexsha, merge_state[("gerrit", "org/project", "master")]) self.assertEqual(ref_map[foobar_zuul_ref].commit.hexsha, merge_state[("gerrit", "org/project", "foo/bar")]) # Delete the remote branch so a reset cleanes up the local branch parent_repo.delete_head('foo/bar', force=True) # Note: Before git 2.13 deleting a a ref foo/bar leaves an empty # directory foo behind that will block creating the reference foo # in the future. As a workaround we must clean up empty directories # in .git/refs. if parent_repo.git.version_info[:2] < (2, 13): Repo._cleanup_leaked_ref_dirs(parent_path, None, []) cache_repo.reset() self.assertNotIn(foobar_zuul_ref, [r.path for r in repo.refs]) # Create another head 'foo' that can't be created if the 'foo/bar' # branch wasn't cleaned up properly parent_repo.create_head("foo") # Change B now on branch 'foo' B = self.fake_gerrit.addFakeChange('org/project', 'foo', 'B') item_b = self._item_from_fake_change(B) # Merge A -> B -> C result = merger.mergeChanges([item_a, item_b, item_c]) self.assertIsNotNone(result) merge_state = result[3] foo_zuul_ref = Repo.refNameToZuulRef("foo") ref_map = {r.path: r for r in repo.refs} self.assertIn(foo_zuul_ref, ref_map) self.assertIn(master_zuul_ref, ref_map) self.assertEqual(ref_map[master_zuul_ref].commit.hexsha, merge_state[("gerrit", "org/project", "master")]) self.assertEqual(ref_map[foo_zuul_ref].commit.hexsha, merge_state[("gerrit", "org/project", "foo")])