diff options
author | Valentin David <valentin.david@gmail.com> | 2019-01-16 10:33:52 +0000 |
---|---|---|
committer | Valentin David <valentin.david@gmail.com> | 2019-01-16 10:33:52 +0000 |
commit | c0631d48c1b1bbfa941bc9eaf7cd5aac2a1ae926 (patch) | |
tree | 0b16dbd2584d57381be581ac6a72981dbfa5695a | |
parent | ecae4d73661d09b249d7ba374fc8722813a13682 (diff) | |
parent | a405e08f7c3fb41a16dfd70fc1630069221aa453 (diff) | |
download | buildstream-c0631d48c1b1bbfa941bc9eaf7cd5aac2a1ae926.tar.gz |
Merge branch 'valentindavid/git-reduced-history' into 'master'
buildstream/_gitsourcebase.py: Reduce git history for git describe.
See merge request BuildStream/buildstream!1069
-rw-r--r-- | buildstream/_gitsourcebase.py | 30 | ||||
-rw-r--r-- | tests/sources/git.py | 189 |
2 files changed, 207 insertions, 12 deletions
diff --git a/buildstream/_gitsourcebase.py b/buildstream/_gitsourcebase.py index 31a1cf66b..4ee870d99 100644 --- a/buildstream/_gitsourcebase.py +++ b/buildstream/_gitsourcebase.py @@ -296,18 +296,24 @@ class GitMirror(SourceFetcher): shallow = set() for _, commit_ref, _ in self.tags: - _, out = self.source.check_output([self.source.host_git, 'rev-list', - '--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 f9aa62ba4..e0560fe5d 100644 --- a/tests/sources/git.py +++ b/tests/sources/git.py @@ -885,6 +885,195 @@ 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) + + project_config = _yaml.load(os.path.join(project, 'project.conf')) + project_config['ref-storage'] = 'project.refs' + _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)) + repo.create(repofiles) + + file1 = os.path.join(str(tmpdir), 'file1') + with open(file1, 'w') as f: + f.write('test\n') + repo.add_file(file1) + repo.branch('branch') + repo.checkout('master') + + file2 = os.path.join(str(tmpdir), 'file2') + with open(file2, 'w') as f: + f.write('test\n') + repo.add_file(file2) + + file3 = os.path.join(str(tmpdir), 'file3') + with open(file3, 'w') as f: + f.write('test\n') + branch_boundary = repo.add_file(file3) + + repo.checkout('branch') + file4 = os.path.join(str(tmpdir), 'file4') + with open(file4, 'w') as f: + f.write('test\n') + tagged_ref = repo.add_file(file4) + repo.add_annotated_tag('tag1', 'tag1') + + head = repo.merge('master') + + config = repo.source_config() + config['track'] = head + 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) + + result = cli.run(project=project, args=['source', 'track', 'target.bst', '--deps', 'all']) + result.assert_success() + + 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() + + describe = subprocess.check_output(['git', 'describe'], + cwd=checkout).decode('ascii') + assert describe.startswith('tag1-2-') + + rev_list = subprocess.check_output(['git', 'rev-list', '--all'], + cwd=checkout).decode('ascii') + + assert set(rev_list.splitlines()) == set([head, tagged_ref, branch_boundary]) + + +@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available") +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template')) def test_default_do_not_track_tags(cli, tmpdir, datafiles): project = str(datafiles) |