# HG changeset patch
# User Georges Racinet <georges.racinet@octobus.net>
# Date 1593281009 -7200
#      Sat Jun 27 20:03:29 2020 +0200
# Node ID f39ef3a8df106aab87c04fdc9257dd36ce699e46
# Parent  4c1edf90a5a1055e22e36139d09721e1ead3004a
repository_service: RepositoryExists and HasLocalBranches

These two methods are called early by the Rails application.

diff --git a/hgitaly/service/repository_service.py b/hgitaly/service/repository_service.py
--- a/hgitaly/service/repository_service.py
+++ b/hgitaly/service/repository_service.py
@@ -5,10 +5,21 @@
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
 import logging
+from mercurial import (
+    error,
+)
+
 # TODO move that to the heptapod package
 from hgext3rd.heptapod.git import git_branch_from_ref
 
+from ..branch import (
+    iter_gitlab_branches,
+)
 from ..stub.repository_service_pb2 import (
+    RepositoryExistsRequest,
+    RepositoryExistsResponse,
+    HasLocalBranchesRequest,
+    HasLocalBranchesResponse,
     WriteRefRequest,
     WriteRefResponse,
 )
@@ -22,6 +33,27 @@
 class RepositoryServiceServicer(RepositoryServiceServicer, HGitalyServicer):
     """RepositoryServiceService implementation.
     """
+
+    def RepositoryExists(self,
+                         request: RepositoryExistsRequest,
+                         context) -> RepositoryExistsResponse:
+        try:
+            self.load_repo(request.repository)
+            exists = True
+        except error.RepoError:
+            exists = False
+
+        return RepositoryExistsResponse(exists=exists)
+
+    def HasLocalBranches(self,
+                         request: HasLocalBranchesRequest,
+                         context) -> HasLocalBranchesResponse:
+        repo = self.load_repo(request.repository)
+        # the iteration should stop as soon at first branchmap entry which
+        # has a non closed head (but all heads in that entry would be checked
+        # to be non closed)
+        return HasLocalBranchesResponse(value=any(iter_gitlab_branches(repo)))
+
     def WriteRef(
             self,
             request: WriteRefRequest,
diff --git a/hgitaly/service/tests/test_repository_service.py b/hgitaly/service/tests/test_repository_service.py
new file mode 100644
--- /dev/null
+++ b/hgitaly/service/tests/test_repository_service.py
@@ -0,0 +1,52 @@
+# Copyright 2020 Georges Racinet <georges.racinet@octobus.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+import shutil
+
+from hgitaly.tests.common import make_empty_repo
+
+from hgitaly.stub.repository_service_pb2 import (
+    HasLocalBranchesRequest,
+    RepositoryExistsRequest,
+)
+from hgitaly.stub.repository_service_pb2_grpc import RepositoryServiceStub
+
+
+def test_repository_exists(grpc_channel, server_repos_root):
+    repo_stub = RepositoryServiceStub(grpc_channel)
+    wrapper, grpc_repo = make_empty_repo(server_repos_root)
+
+    def exists(repo):
+        return repo_stub.RepositoryExists(
+            RepositoryExistsRequest(repository=repo)).exists
+
+    assert exists(grpc_repo)
+
+    # directory exists but is not a Mercurial repo
+    shutil.rmtree(wrapper.path / '.hg')
+    assert not exists(grpc_repo)
+
+    # directory does not exist
+    grpc_repo.relative_path = 'does/not/exist'
+    assert not exists(grpc_repo)
+
+
+def test_has_local_branches(grpc_channel, server_repos_root):
+    repo_stub = RepositoryServiceStub(grpc_channel)
+    wrapper, grpc_repo = make_empty_repo(server_repos_root)
+
+    def has_local_branches():
+        return repo_stub.HasLocalBranches(
+            HasLocalBranchesRequest(repository=grpc_repo)).value
+
+    assert not has_local_branches()
+    wrapper.write_commit('foo')
+    assert has_local_branches()
+
+    wrapper.command('commit', message=b"closing the only head!",
+                    close_branch=True)
+
+    assert not has_local_branches()