From f2fcc2f6ff6e2000e75a078ab024235173936b8f Mon Sep 17 00:00:00 2001 From: Valentin David Date: Fri, 7 Dec 2018 16:59:41 +0100 Subject: Force updating tags when fetching git repository When using aliases there are multiple remotes used in the cache repository. When fetching, tags are not updated if the were previously fetched from a different remote. Commits that not in a branch and only tagged do not get fetched if the tag is not fetched. Fixes #812 --- buildstream/plugins/sources/git.py | 2 +- tests/sources/git.py | 98 ++++++++++++++++++++++++++++++++++++++ tests/testutils/repo/git.py | 5 +- 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/buildstream/plugins/sources/git.py b/buildstream/plugins/sources/git.py index ae8f36bfe..74d632b6d 100644 --- a/buildstream/plugins/sources/git.py +++ b/buildstream/plugins/sources/git.py @@ -247,7 +247,7 @@ class GitMirror(SourceFetcher): else: remote_name = "origin" - self.source.call([self.source.host_git, 'fetch', remote_name, '--prune'], + self.source.call([self.source.host_git, 'fetch', remote_name, '--prune', '--force', '--tags'], fail="Failed to fetch from remote git repository: {}".format(url), fail_temporarily=True, cwd=self.mirror) diff --git a/tests/sources/git.py b/tests/sources/git.py index b9251e36a..c9e806269 100644 --- a/tests/sources/git.py +++ b/tests/sources/git.py @@ -23,6 +23,7 @@ import os import pytest import subprocess +import shutil from buildstream._exceptions import ErrorDomain from buildstream import _yaml @@ -920,3 +921,100 @@ def test_default_do_not_track_tags(cli, tmpdir, datafiles): element = _yaml.load(element_path) assert 'tags' not in element['sources'][0] + + +@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available") +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template')) +def test_overwrite_rogue_tag_multiple_remotes(cli, tmpdir, datafiles): + """When using multiple remotes in cache (i.e. when using aliases), we + need to make sure we override tags. This is not allowed to fetch + tags that were present from different origins + """ + + project = str(datafiles) + + repofiles = os.path.join(str(tmpdir), 'repofiles') + os.makedirs(repofiles, exist_ok=True) + file0 = os.path.join(repofiles, 'file0') + with open(file0, 'w') as f: + f.write('test\n') + + repo = create_repo('git', str(tmpdir)) + + top_commit = repo.create(repofiles) + + repodir, reponame = os.path.split(repo.repo) + project_config = _yaml.load(os.path.join(project, 'project.conf')) + project_config['aliases'] = { + 'repo': 'http://example.com/' + } + project_config['mirrors'] = [ + { + 'name': 'middle-earth', + 'aliases': { + 'repo': ['file://{}/'.format(repodir)] + } + } + ] + _yaml.dump(_yaml.node_sanitize(project_config), os.path.join(project, 'project.conf')) + + repo.add_annotated_tag('tag', 'tag') + + file1 = os.path.join(repofiles, 'file1') + with open(file1, 'w') as f: + f.write('test\n') + + ref = repo.add_file(file1) + + config = repo.source_config(ref=ref) + del config['track'] + config['url'] = 'repo:{}'.format(reponame) + + # Write out our test target + element = { + 'kind': 'import', + 'sources': [ + config + ], + } + element_path = os.path.join(project, 'target.bst') + _yaml.dump(element, element_path) + + result = cli.run(project=project, args=['build', 'target.bst']) + result.assert_success() + + repo.checkout(top_commit) + + file2 = os.path.join(repofiles, 'file2') + with open(file2, 'w') as f: + f.write('test\n') + + new_ref = repo.add_file(file2) + + repo.delete_tag('tag') + repo.add_annotated_tag('tag', 'tag') + repo.checkout('master') + + otherpath = os.path.join(str(tmpdir), 'other_path') + shutil.copytree(repo.repo, + os.path.join(otherpath, 'repo')) + new_repo = create_repo('git', otherpath) + + repodir, reponame = os.path.split(repo.repo) + + _yaml.dump(_yaml.node_sanitize(project_config), os.path.join(project, 'project.conf')) + + config = repo.source_config(ref=new_ref) + del config['track'] + config['url'] = 'repo:{}'.format(reponame) + + element = { + 'kind': 'import', + 'sources': [ + config + ], + } + _yaml.dump(element, element_path) + + result = cli.run(project=project, args=['build', 'target.bst']) + result.assert_success() diff --git a/tests/testutils/repo/git.py b/tests/testutils/repo/git.py index b2d480975..3eb8c6577 100644 --- a/tests/testutils/repo/git.py +++ b/tests/testutils/repo/git.py @@ -99,12 +99,15 @@ class Git(Repo): return config def latest_commit(self): - output = self._run_git('rev-parse', 'master', stdout=subprocess.PIPE).stdout + output = self._run_git('rev-parse', 'HEAD', stdout=subprocess.PIPE).stdout return output.decode('UTF-8').strip() def branch(self, branch_name): self._run_git('checkout', '-b', branch_name) + def delete_tag(self, tag_name): + self._run_git('tag', '-d', tag_name) + def checkout(self, commit): self._run_git('checkout', commit) -- cgit v1.2.1