diff --git a/hgitaly/servicer.py b/hgitaly/servicer.py
index dc2defecd55ca00735ea4a143f517f01e666a84e_aGdpdGFseS9zZXJ2aWNlci5weQ==..15c56172544ffbbafc4bb202096de0a890a07cea_aGdpdGFseS9zZXJ2aWNlci5weQ== 100644
--- a/hgitaly/servicer.py
+++ b/hgitaly/servicer.py
@@ -4,6 +4,7 @@
 # GNU General Public License version 2 or any later version.
 #
 # SPDX-License-Identifier: GPL-2.0-or-later
+from contextlib import contextmanager
 import gc
 import logging
 import os
@@ -7,6 +8,7 @@
 import gc
 import logging
 import os
+from pathlib import Path
 import time
 import weakref
 
@@ -17,6 +19,8 @@
     ui as uimod,
 )
 from mercurial.repoview import _filteredrepotypes
+
+from .workdir import working_directory
 from .stub.shared_pb2 import (
     Repository,
 )
@@ -253,3 +257,19 @@
             os.mkdir(to_create.pop(), mode=0o755)
 
         return temp_dir
+
+    @contextmanager
+    def working_dir(self, gl_repo: Repository, repo, context, changeset=None):
+        """Provide a working directory updated to the given changeset.
+
+        The working directory is part from the pool of reusable working
+        directories and created if needed.
+        """
+        tmp = Path(os.fsdecode(
+            self.temp_dir(gl_repo.storage_name, context, ensure=True)
+        ))
+        rpath = normalize_rpath(gl_repo)
+
+        with working_directory(tmp / 'workdirs' / rpath, repo,
+                               changeset=changeset) as wd:
+            yield wd
diff --git a/hgitaly/tests/test_servicer.py b/hgitaly/tests/test_servicer.py
index dc2defecd55ca00735ea4a143f517f01e666a84e_aGdpdGFseS90ZXN0cy90ZXN0X3NlcnZpY2VyLnB5..15c56172544ffbbafc4bb202096de0a890a07cea_aGdpdGFseS90ZXN0cy90ZXN0X3NlcnZpY2VyLnB5 100644
--- a/hgitaly/tests/test_servicer.py
+++ b/hgitaly/tests/test_servicer.py
@@ -182,3 +182,37 @@
     with pytest.raises(AbortContext):
         servicer.temp_dir('broken', context, ensure=True)
     assert context.code == grpc.StatusCode.INTERNAL
+
+
+def test_working_dir(tmpdir):
+    context = FakeContext()
+    servicer = HGitalyServicer(dict(default=as_bytes(tmpdir)))
+
+    storage_root = tmpdir.join('repos')
+    storage_root_bytes = pycompat.sysbytes(str(storage_root))
+    servicer = HGitalyServicer(dict(storname=storage_root_bytes))
+    # context is used for error raising only
+    context = FakeContext()
+
+    wrapper = LocalRepoWrapper.init(storage_root.join('awesome-proj.hg'))
+    gl_repo = Repository(storage_name='storname',
+                         relative_path='awesome-proj.hg')
+    repo = servicer.load_repo(gl_repo, context)
+
+    with servicer.working_dir(gl_repo, repo, context) as wd:
+        wd_path = wd.path
+        wd_wrapper = LocalRepoWrapper.load(wd_path)
+        sha = wd_wrapper.commit_file('foo').hex()
+
+    wrapper.reload()
+    ctx = wrapper.repo[sha]
+    assert ctx.hex() == sha
+
+    with servicer.working_dir(gl_repo, repo, context, changeset=ctx) as wd:
+        assert wd.path == wd_path
+        wd_wrapper.reload()
+        sha2 = wd_wrapper.commit_file('nar').hex()
+
+    wrapper.reload()
+    ctx2 = wrapper.repo[sha2]
+    assert ctx2.hex() == sha2