Esempio n. 1
0
    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")
Esempio n. 2
0
    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")])