def test_broken_cache(self): parent_path = os.path.join(self.upstream_root, 'org/project1') work_repo = Repo(parent_path, self.workspace_root, '*****@*****.**', 'User Name', '0', '0') self.waitUntilSettled() # Break the work repo path = work_repo.local_path os.remove(os.path.join(path, '.git/HEAD')) # And now reset the repo again. This should not crash work_repo.reset()
def test_branch_rename(self): parent_path = os.path.join(self.upstream_root, 'org/project1') # Clone upstream so that current head is master work_repo = Repo(parent_path, self.workspace_root, '*****@*****.**', 'User Name', '0', '0') # Rename master to main in upstream repo gitrepo = git.Repo(parent_path) main_branch = gitrepo.create_head('main') gitrepo.head.reference = main_branch gitrepo.delete_head(gitrepo.heads['master'], force=True) # And now reset the repo. This should not crash work_repo.reset()
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_broken_gitmodules(self): parent_path = os.path.join(self.upstream_root, 'org/project1') work_repo = Repo(parent_path, self.workspace_root, '*****@*****.**', 'User Name', '0', '0') self.waitUntilSettled() # Break the gitmodules path = work_repo.local_path with open(os.path.join(path, '.gitmodules'), 'w') as f: f.write('[submodule "libfoo"]\n' 'path = include/foo\n' '---\n' 'url = git://example.com/git/lib.git') # And now reset the repo again. This should not crash work_repo.reset()
def test_deleted_local_ref(self): parent_path = os.path.join(self.upstream_root, 'org/project1') self.create_branch('org/project1', 'foobar') work_repo = Repo(parent_path, self.workspace_root, '*****@*****.**', 'User Name', '0', '0') # Delete local ref on the cached repo. This leaves us with a remote # ref but no local ref anymore. gitrepo = git.Repo(work_repo.local_path) gitrepo.delete_head('foobar', force=True) # Delete the branch upstream. self.delete_branch('org/project1', 'foobar') # And now reset the repo again. This should not crash work_repo.reset()
def test_broken_cache(self): parent_path = os.path.join(self.upstream_root, 'org/project1') work_repo = Repo(parent_path, self.workspace_root, '*****@*****.**', 'User Name', '0', '0') self.waitUntilSettled() # Break the work repo path = work_repo.local_path os.remove(os.path.join(path, '.git/HEAD')) # And now reset the repo again. This should not crash work_repo.reset() # Now open a cache repo and break it in a way that git.Repo is happy # at first but git won't be because of a broken HEAD revision. merger = self.executor_server.merger cache_repo = merger.getRepo('gerrit', 'org/project') with open(os.path.join(cache_repo.local_path, '.git/HEAD'), 'w'): pass cache_repo.update() # Now open a cache repo and break it in a way that git.Repo is happy # at first but git won't be because of a corrupt object file. # # To construct this we create a commit so we have a guaranteed free # object file, then we break it by truncating it. fn = os.path.join(cache_repo.local_path, 'commit_filename') with open(fn, 'a') as f: f.write("test") repo = cache_repo.createRepoObject(None) repo.index.add([fn]) repo.index.commit('test commit') # Pick the first object file we find and break it objects_path = os.path.join(cache_repo.local_path, '.git', 'objects') object_dir = os.path.join(objects_path, [ d for d in os.listdir(objects_path) if len(d) == 2 ][0]) object_to_break = os.path.join(object_dir, os.listdir(object_dir)[0]) self.log.error(os.stat(object_to_break)) os.chmod(object_to_break, 644) with open(object_to_break, 'w'): pass os.chmod(object_to_break, 444) cache_repo.update()
def test_broken_cache(self): parent_path = os.path.join(self.upstream_root, 'org/project1') work_repo = Repo(parent_path, self.workspace_root, '*****@*****.**', 'User Name', '0', '0') self.waitUntilSettled() # Break the work repo path = work_repo.local_path os.remove(os.path.join(path, '.git/HEAD')) # And now reset the repo again. This should not crash work_repo.reset() # Now open a cache repo and break it in a way that git.Repo is happy # at first but git won't be. merger = self.executor_server.merger cache_repo = merger.getRepo('gerrit', 'org/project') with open(os.path.join(cache_repo.local_path, '.git/HEAD'), 'w'): pass cache_repo.update()