diff --git a/hgitaly/revision.py b/hgitaly/revision.py index 364d32a1513ca505531d845f7ea88ee14af7b145_aGdpdGFseS9yZXZpc2lvbi5weQ==..88981e79d7de9dd2e43a148e4850266ffd765ffb_aGdpdGFseS9yZXZpc2lvbi5weQ== 100644 --- a/hgitaly/revision.py +++ b/hgitaly/revision.py @@ -22,9 +22,12 @@ from heptapod.gitlab.branch import ( gitlab_branch_from_ref, ) +from heptapod.gitlab.tag import ( + gitlab_tag_from_ref, +) from .branch import ( gitlab_branch_head ) from .gitlab_ref import ( gitlab_special_ref_target ) @@ -25,9 +28,10 @@ from .branch import ( gitlab_branch_head ) from .gitlab_ref import ( gitlab_special_ref_target ) +from .tag import tagged_changeset logger = logging.getLogger(__name__) @@ -75,7 +79,10 @@ return None # non ambigous ref forms: they should obviously take precedence - # TODO direct reference to tag here as well + gl_tag = gitlab_tag_from_ref(revision) + if gl_tag is not None: + return tagged_changeset(repo, gl_tag) + gl_branch = gitlab_branch_from_ref(revision) if gl_branch is not None: # can return None diff --git a/hgitaly/service/tests/test_commit.py b/hgitaly/service/tests/test_commit.py index 364d32a1513ca505531d845f7ea88ee14af7b145_aGdpdGFseS9zZXJ2aWNlL3Rlc3RzL3Rlc3RfY29tbWl0LnB5..88981e79d7de9dd2e43a148e4850266ffd765ffb_aGdpdGFseS9zZXJ2aWNlL3Rlc3RzL3Rlc3RfY29tbWl0LnB5 100644 --- a/hgitaly/service/tests/test_commit.py +++ b/hgitaly/service/tests/test_commit.py @@ -198,6 +198,7 @@ utc_timestamp=now, message="A single line", user="HGitaly Test <hgitaly@heptapod.test>") + wrapper.command('tag', b'testtag', rev=ctx.hex()) ctx2 = wrapper.commit_file('foo', tz_timestamp=(123456, -7200), # UTC+2 parent=ctx, @@ -238,6 +239,9 @@ assert commit_top is not None assert commit_top.subject == b"in topic" + # a tag + assert find_commit(b'testtag').commit == commit + # with revision given in full "ref" form assert find_commit( b'refs/heads/topic/default/antelope').commit == commit_top @@ -241,6 +245,7 @@ # with revision given in full "ref" form assert find_commit( b'refs/heads/topic/default/antelope').commit == commit_top + assert find_commit(b'refs/tags/testtag').commit == commit # with explicitely set default GitLab branch: set_default_gitlab_branch(wrapper.repo, b'topic/default/antelope') @@ -253,6 +258,13 @@ # with unknown changeset assert not find_commit(b'unknown').HasField('commit') + # 'tip' is not a valid tag + # TODO avoid resolving it when given in implicit form (just 'tip') + # but that requires not fallbacking to scmutil.revsingle and is not + # suited for the current work on stable branch. + assert not find_commit(b'refs/tags/tip').HasField('commit') + assert not find_commit(b'refs/tags/unknown').HasField('commit') + # special cases of invalid commit ids (prefix or not) assert not find_commit(b'f' * 39).HasField('commit') assert not find_commit(b'f' * 40).HasField('commit') diff --git a/hgitaly/tag.py b/hgitaly/tag.py index 364d32a1513ca505531d845f7ea88ee14af7b145_aGdpdGFseS90YWcucHk=..88981e79d7de9dd2e43a148e4850266ffd765ffb_aGdpdGFseS90YWcucHk= 100644 --- a/hgitaly/tag.py +++ b/hgitaly/tag.py @@ -36,3 +36,16 @@ """ for name, target in iter_gitlab_tags(repo, **kwargs): yield gitlab_tag_ref(name), target + + +def tagged_changeset(repo, tag_name): + """Return the changeset that the given tags points to, or None. + + :return: a changectx. + """ + tags = repo.tags() + node = tags.get(tag_name) + if node is None or repo.tagtype(tag_name) in EXCLUDED_TAG_TYPES: + return None # voluntarily explit + + return repo[node] diff --git a/tests_with_gitaly/test_commit.py b/tests_with_gitaly/test_commit.py index 364d32a1513ca505531d845f7ea88ee14af7b145_dGVzdHNfd2l0aF9naXRhbHkvdGVzdF9jb21taXQucHk=..88981e79d7de9dd2e43a148e4850266ffd765ffb_dGVzdHNfd2l0aF9naXRhbHkvdGVzdF9jb21taXQucHk= 100644 --- a/tests_with_gitaly/test_commit.py +++ b/tests_with_gitaly/test_commit.py @@ -229,7 +229,8 @@ assert_compare(revision=b'topic/default/sampletop') assert_compare(revision=b'refs/heads/topic/default/sampletop') assert_compare(revision=b'start-tag') - # TODO refs/tags not implemented! + assert_compare(revision=b'refs/tags/start-tag') + assert_compare(revision=b'refs/tags/unknown') # TODO special refs and keep-arounds # TODO cases of collision/shadowing