There will be about 1h of downtime on 2020-03-02 at 13:00 UTC+1 (change of servers and upgrade to Heptapod 0.20.0 final)

Commit 6c14a3cd authored by Sushil Khanchi's avatar Sushil Khanchi 🐨

RefService: add FindRefName method

parent 0e78099a98da
......@@ -8,6 +8,7 @@ import logging
from mercurial import (
pycompat,
node as nodemod,
)
from heptapod.gitlab.branch import (
......@@ -17,7 +18,6 @@ from heptapod.gitlab.branch import (
from hgext3rd.heptapod.branch import get_default_gitlab_branch
from ..errors import (
not_implemented,
not_found,
)
from ..stub.shared_pb2 import (
......@@ -159,7 +159,17 @@ class RefServicer(RefServiceServicer, HGitalyServicer):
As of GitLab 12.10, there is no caller for this Repository method
in the whole Rails application.
"""
not_implemented(context, issue=9) # pragma no cover
try:
node = nodemod.bin(request.commit_id)
except TypeError:
return FindRefNameResponse(name=b"")
repo = self.load_repo(request.repository, context)
prefix = request.prefix
cl = repo.changelog
if not (len(node) == len(nodemod.nullid) and cl.hasnode(node)):
# node id doesn't exists
return FindRefNameResponse(name=b"")
return findRefName(repo, node, prefix)
def FindLocalBranches(self,
request: FindLocalBranchesRequest,
......@@ -408,3 +418,34 @@ TAG_REF_PREFIX = b'refs/tags/'
def gitlab_tag_from_ref(ref):
if ref.startswith(TAG_REF_PREFIX):
return ref[len(TAG_REF_PREFIX):]
def findRefName(repo, node, prefix):
ctx = repo[node]
if ctx.closesbranch():
return FindRefNameResponse(name=b"")
if ctx.topic():
ref_name = prefix + b"/topic/%s/" % (ctx.branch()) + ctx.topic()
else:
bheads = repo.branchheads(branch=ctx.branch())
if not bheads:
return FindRefNameResponse(name=b"")
tipofheads = bheads[0]
allbkmarks = repo.revs(b"%d:: and bookmark()" % ctx.rev())
possiblerefs = list(map(lambda rev: repo[rev].bookmarks()[0],
allbkmarks))
if ctx.isancestorof(repo[tipofheads]):
possiblerefs.append(b"branch/" + ctx.branch())
elif possiblerefs:
# bookmark present on wild heads line, so bookmark gets preference
pass
else:
# ctx is an ancestor of wild heads only
heads = repo.revs(b"heads(%d::) and branch(%s) and not topic()" %
(ctx.rev(), ctx.branch()))
refrevision = max(heads)
ref_name = prefix + b"/wild/" + repo[refrevision].hex()
return FindRefNameResponse(name=ref_name)
possiblerefs.sort()
ref_name = prefix + b"/" + possiblerefs[0]
return FindRefNameResponse(name=ref_name)
......@@ -25,6 +25,7 @@ from hgitaly.stub.ref_pb2 import (
FindLocalBranchesRequest,
FindAllRemoteBranchesRequest,
FindAllBranchesRequest,
FindRefNameRequest,
DeleteRefsRequest,
ListBranchNamesContainingCommitRequest,
ListTagNamesContainingCommitRequest,
......@@ -36,6 +37,75 @@ from hgitaly.stub.ref_pb2 import (
from hgitaly.stub.ref_pb2_grpc import RefServiceStub
def test_find_ref_name(grpc_channel, server_repos_root):
ref_stub = RefServiceStub(grpc_channel)
wrapper, grpc_repo = make_empty_repo(server_repos_root)
ctx0 = wrapper.write_commit('foo')
ctx1 = wrapper.write_commit('foo', topic='feature')
wrapper.update(0)
ctx2 = wrapper.write_commit('foo')
ctx3 = wrapper.write_commit('foo')
wrapper.command('bookmark', b'first@')
wrapper.update(0)
ctx4 = wrapper.write_commit('foo')
ctx5 = wrapper.write_commit('foo')
wrapper.update(0)
ctx6 = wrapper.write_commit('foo')
wrapper.command('bookmark', b'second@')
wrapper.update(0)
ctx7 = wrapper.write_commit('foo')
# repo structure:
#
# @ changeset: 7
# | tag: tip
# |
# | o changeset: 6
# |/ bookmark: second@
# |
# | o changeset: 5
# | |
# | o changeset: 4
# |/
# |
# | o changeset: 3
# | | bookmark: first@
# | |
# | o changeset: 2
# |/
# |
# | o changeset: 1
# |/ topic: feature
# |
# o changeset: 0
#
def do_rpc(commit_id):
request = FindRefNameRequest(repository=grpc_repo,
commit_id=commit_id,
prefix=b"refs/heads")
return ref_stub.FindRefName(request).name
assert do_rpc(ctx0.hex()) == b"refs/heads/branch/default"
assert do_rpc(ctx1.hex()) == b"refs/heads/topic/default/feature"
assert do_rpc(ctx2.hex()) == b"refs/heads/first@"
assert do_rpc(ctx3.hex()) == b"refs/heads/first@"
assert do_rpc(ctx4.hex()) == b"refs/heads/wild/%s" % ctx5.hex()
assert do_rpc(ctx5.hex()) == b"refs/heads/wild/%s" % ctx5.hex()
assert do_rpc(ctx6.hex()) == b"refs/heads/second@"
assert do_rpc(ctx7.hex()) == b"refs/heads/branch/default"
# testing for an invalid node
assert do_rpc("1111111") == b''
# testing for a node which doesn't exist
assert do_rpc("71341525cbf376d33bee8e9096cf185792495856") == b''
# testing on a closed branch
wrapper.command('branch', b'stable')
ctx8 = wrapper.write_commit('foo')
wrapper.command('commit', message=b'closing stable', close_branch=True)
assert do_rpc(ctx8.hex()) == b""
assert do_rpc(wrapper.repo[9].hex()) == b""
def test_find_all_branch_names(grpc_channel, server_repos_root):
ref_stub = RefServiceStub(grpc_channel)
wrapper, grpc_repo = make_empty_repo(server_repos_root)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment