summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin David <valentin.david@codethink.co.uk>2019-01-15 14:01:53 +0100
committerValentin David <valentin.david@codethink.co.uk>2019-01-15 17:30:45 +0100
commit6832c3da5c31f5303c832ee3c90d4956f6ff7c72 (patch)
tree48ecb37cbaeff98d25fe5edd58d434eb14c38243
parente4788ddee68a550ee2e06be1d6ee58205bf2e753 (diff)
downloadbuildstream-valentindavid/git-reduced-history.tar.gz
buildstream/_gitsourcebase.py: Fix case where HEAD is taggedvalentindavid/git-reduced-history
`git rev-list --boundary HEAD..HEAD` does not return any boundary. So in this case we need to manually tag the HEAD as a boundary.
-rw-r--r--buildstream/_gitsourcebase.py31
-rw-r--r--tests/sources/git.py111
2 files changed, 129 insertions, 13 deletions
diff --git a/buildstream/_gitsourcebase.py b/buildstream/_gitsourcebase.py
index a71f70bdc..4ee870d99 100644
--- a/buildstream/_gitsourcebase.py
+++ b/buildstream/_gitsourcebase.py
@@ -296,19 +296,24 @@ class GitMirror(SourceFetcher):
shallow = set()
for _, commit_ref, _ in self.tags:
- _, out = self.source.check_output([self.source.host_git, 'rev-list',
- '--ancestry-path', '--boundary',
- '{}..{}'.format(commit_ref, self.ref)],
- fail="Failed to get git history {}..{} in directory: {}"
- .format(commit_ref, self.ref, fullpath),
- fail_temporarily=True,
- cwd=self.mirror)
- for line in out.splitlines():
- rev = line.lstrip('-')
- if line[0] == '-':
- shallow.add(rev)
- else:
- included.add(rev)
+ if commit_ref == self.ref:
+ # rev-list does not work in case of same rev
+ shallow.add(self.ref)
+ else:
+ _, out = self.source.check_output([self.source.host_git, 'rev-list',
+ '--ancestry-path', '--boundary',
+ '{}..{}'.format(commit_ref, self.ref)],
+ fail="Failed to get git history {}..{} in directory: {}"
+ .format(commit_ref, self.ref, fullpath),
+ fail_temporarily=True,
+ cwd=self.mirror)
+ self.source.warn("refs {}..{}: {}".format(commit_ref, self.ref, out.splitlines()))
+ for line in out.splitlines():
+ rev = line.lstrip('-')
+ if line[0] == '-':
+ shallow.add(rev)
+ else:
+ included.add(rev)
shallow -= included
included |= shallow
diff --git a/tests/sources/git.py b/tests/sources/git.py
index 431f61845..f3ce43b5e 100644
--- a/tests/sources/git.py
+++ b/tests/sources/git.py
@@ -885,6 +885,117 @@ def test_git_describe(cli, tmpdir, datafiles, ref_storage, tag_type):
@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")
@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template'))
+@pytest.mark.parametrize("ref_storage", [('inline'), ('project.refs')])
+@pytest.mark.parametrize("tag_type", [('annotated'), ('lightweight')])
+def test_git_describe_head_is_tagged(cli, tmpdir, datafiles, ref_storage, tag_type):
+ project = str(datafiles)
+
+ project_config = _yaml.load(os.path.join(project, 'project.conf'))
+ project_config['ref-storage'] = ref_storage
+ _yaml.dump(_yaml.node_sanitize(project_config), os.path.join(project, 'project.conf'))
+
+ 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))
+
+ def tag(name):
+ if tag_type == 'annotated':
+ repo.add_annotated_tag(name, name)
+ else:
+ repo.add_tag(name)
+
+ ref = repo.create(repofiles)
+ tag('uselesstag')
+
+ file1 = os.path.join(str(tmpdir), 'file1')
+ with open(file1, 'w') as f:
+ f.write('test\n')
+ repo.add_file(file1)
+
+ file2 = os.path.join(str(tmpdir), 'file2')
+ with open(file2, 'w') as f:
+ f.write('test\n')
+ repo.branch('branch2')
+ repo.add_file(file2)
+
+ repo.checkout('master')
+ file3 = os.path.join(str(tmpdir), 'file3')
+ with open(file3, 'w') as f:
+ f.write('test\n')
+ repo.add_file(file3)
+
+ tagged_ref = repo.merge('branch2')
+ tag('tag')
+
+ config = repo.source_config()
+ config['track'] = repo.latest_commit()
+ config['track-tags'] = True
+
+ # Write out our test target
+ element = {
+ 'kind': 'import',
+ 'sources': [
+ config
+ ],
+ }
+ element_path = os.path.join(project, 'target.bst')
+ _yaml.dump(element, element_path)
+
+ if ref_storage == 'inline':
+ result = cli.run(project=project, args=['source', 'track', 'target.bst'])
+ result.assert_success()
+ else:
+ result = cli.run(project=project, args=['source', 'track', 'target.bst', '--deps', 'all'])
+ result.assert_success()
+
+ if ref_storage == 'inline':
+ element = _yaml.load(element_path)
+ tags = _yaml.node_sanitize(element['sources'][0]['tags'])
+ assert len(tags) == 1
+ for tag in tags:
+ assert 'tag' in tag
+ assert 'commit' in tag
+ assert 'annotated' in tag
+ assert tag['annotated'] == (tag_type == 'annotated')
+
+ assert set([(tag['tag'], tag['commit']) for tag in tags]) == set([('tag', repo.rev_parse('tag^{commit}'))])
+
+ checkout = os.path.join(str(tmpdir), 'checkout')
+
+ result = cli.run(project=project, args=['build', 'target.bst'])
+ result.assert_success()
+ result = cli.run(project=project, args=['checkout', 'target.bst', checkout])
+ result.assert_success()
+
+ if tag_type == 'annotated':
+ options = []
+ else:
+ options = ['--tags']
+ describe = subprocess.check_output(['git', 'describe'] + options,
+ cwd=checkout).decode('ascii')
+ assert describe.startswith('tag')
+
+ tags = subprocess.check_output(['git', 'tag'],
+ cwd=checkout).decode('ascii')
+ tags = set(tags.splitlines())
+ assert tags == set(['tag'])
+
+ rev_list = subprocess.check_output(['git', 'rev-list', '--all'],
+ cwd=checkout).decode('ascii')
+
+ assert set(rev_list.splitlines()) == set([tagged_ref])
+
+ p = subprocess.run(['git', 'log', repo.rev_parse('uselesstag')],
+ cwd=checkout)
+ assert p.returncode != 0
+
+
+@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")
+@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template'))
def test_git_describe_relevant_history(cli, tmpdir, datafiles):
project = str(datafiles)