summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin David <valentin.david@codethink.co.uk>2018-12-07 16:59:41 +0100
committerValentin David <valentin.david@codethink.co.uk>2018-12-11 13:12:08 +0100
commitf2fcc2f6ff6e2000e75a078ab024235173936b8f (patch)
treeb6ffa1c1ef1a776a76ef987c51bb4455c5031009
parent873b618c2f3dbb8c054f9eab7cd3c6c15cbf049c (diff)
downloadbuildstream-valentindavid/git_force_fetch_tags.tar.gz
Force updating tags when fetching git repositoryvalentindavid/git_force_fetch_tags
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
-rw-r--r--buildstream/plugins/sources/git.py2
-rw-r--r--tests/sources/git.py98
-rw-r--r--tests/testutils/repo/git.py5
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)