diff --git a/hgext3rd/heptapod/git.py b/hgext3rd/heptapod/git.py
index c0860aa1c0bb9a54df0c84d3431a4d6e701d0bbf_aGdleHQzcmQvaGVwdGFwb2QvZ2l0LnB5..619676e43dc4f241bfcd4d6a55d0f376fd7f3255_aGdleHQzcmQvaGVwdGFwb2QvZ2l0LnB5 100644
--- a/hgext3rd/heptapod/git.py
+++ b/hgext3rd/heptapod/git.py
@@ -11,6 +11,7 @@
 """
 from __future__ import absolute_import
 
+from mercurial import error
 try:
     from hgext3rd.hggit.git_handler import GitHandler
 except ImportError:  # pragma: no cover (fallback for hg-git < 0.11)
@@ -96,6 +97,41 @@
         if os.path.exists(old_gitdir) and not os.path.exists(self.gitdir):
             os.rename(old_gitdir, self.gitdir)
 
+        self.fixup_git_pool()
+
+    def fixup_git_pool(self):
+        alternates_path = os.path.join(self.gitdir,
+                                       b'objects/info/alternates')
+        if not os.path.exists(alternates_path):
+            return
+
+        with open(alternates_path, 'rb') as alternates:
+            lines = alternates.readlines()
+
+        new_lines = []
+        for line in lines:
+            line = line.strip()
+            tgt_path = os.path.join(self.gitdir, line)
+            if os.path.exists(tgt_path):
+                new_lines.append(line)
+            else:
+                repositories_root = self.repo.ui.config(b'heptapod',
+                                                        b'repositories-root')
+                idx = tgt_path.find(b'@pools/')
+                if idx == -1:
+                    raise error.Abort(
+                        b"Unreachable Git alternates path that is not "
+                        b"under the expected GitLab pools: %r" % tgt_path)
+                abs_tgt = os.path.join(repositories_root, tgt_path[idx:])
+                if not os.path.exists(abs_tgt):
+                    raise error.Abort(
+                        b"After fix, path to shared Git inside GitLab pools "
+                        b"does not exist: %r" % abs_tgt)
+                new_lines.append(os.path.relpath(abs_tgt,
+                                                 self.gitdir + b'/objects'))
+        with open(alternates_path, 'wb') as alternates:
+            alternates.write(b'\n'.join(new_lines))
+
     @property
     def gitlab_refs(self):
         return self.git.refs
diff --git a/hgext3rd/heptapod/tests/git/test_inner.py b/hgext3rd/heptapod/tests/git/test_inner.py
index c0860aa1c0bb9a54df0c84d3431a4d6e701d0bbf_aGdleHQzcmQvaGVwdGFwb2QvdGVzdHMvZ2l0L3Rlc3RfaW5uZXIucHk=..619676e43dc4f241bfcd4d6a55d0f376fd7f3255_aGdleHQzcmQvaGVwdGFwb2QvdGVzdHMvZ2l0L3Rlc3RfaW5uZXIucHk= 100644
--- a/hgext3rd/heptapod/tests/git/test_inner.py
+++ b/hgext3rd/heptapod/tests/git/test_inner.py
@@ -15,6 +15,7 @@
 from mercurial import (
     error,
 )
+from pathlib import Path
 import pytest
 import re
 
@@ -22,6 +23,7 @@
 from heptapod.testhelpers import (
     RepoWrapper,
 )
+from heptapod.testhelpers.git import GitRepo
 from heptapod.gitlab import prune_reasons
 from heptapod.gitlab.branch import gitlab_branch_ref as git_branch_ref
 from heptapod.gitlab.change import GitLabRefChange as RefChange
@@ -39,6 +41,8 @@
 # TODO move to helper module
 from .test_integration import patch_gitlab_hooks
 
+parametrize = pytest.mark.parametrize
+
 
 @pytest.fixture
 def wrapper(tmpdir):
@@ -449,3 +453,36 @@
             fallback=REF_TARGET_UNKNOWN_RAISE)
         )
     assert exc_info.value.args == (unknown_git_sha, )
+
+
+@parametrize('special',
+             ('abspath-not-found', 'relpath-not-found', 'other-alt'))
+def test_fixup_git_pool_special_cases(wrapper, special, tmpdir):
+    wrapper.repo.ui.setconfig(b'heptapod', b'native', True)
+    git_repo = GitRepo.init(wrapper.path / '../repo.git')
+    if special == 'abspath-not-found':
+        alt_path = b'/no/such/path'
+    elif special == 'relpath-not-found':
+        alt_path = b'../@pools/does/not/exist/either'
+    else:
+        alt_path = tmpdir / 'existing'
+        alt_path.mkdir()
+        alt_path = str(alt_path).encode('utf-8')
+    conf_relpath = 'objects/info/alternates'
+    (git_repo.path / conf_relpath).write_binary(alt_path)
+
+    handler = HeptapodGitHandler(wrapper.repo, wrapper.repo.ui)
+    if special == 'other-alt':
+        handler.native_project_ensure_set_git_dir()
+        moved_path = Path(handler.gitdir.decode())
+        assert moved_path != git_repo.path
+        assert (moved_path / conf_relpath).read_bytes() == alt_path
+        return
+
+    with pytest.raises(error.Abort) as exc_info:
+        handler.native_project_ensure_set_git_dir()
+    if special == 'abspath-not-found':
+        expected_msg = b'Unreachable Git alternates'
+    else:
+        expected_msg = b'path to shared Git inside GitLab pools'
+    assert expected_msg in exc_info.value.args[0]
diff --git a/hgext3rd/heptapod/tests/git/test_integration.py b/hgext3rd/heptapod/tests/git/test_integration.py
index c0860aa1c0bb9a54df0c84d3431a4d6e701d0bbf_aGdleHQzcmQvaGVwdGFwb2QvdGVzdHMvZ2l0L3Rlc3RfaW50ZWdyYXRpb24ucHk=..619676e43dc4f241bfcd4d6a55d0f376fd7f3255_aGdleHQzcmQvaGVwdGFwb2QvdGVzdHMvZ2l0L3Rlc3RfaW50ZWdyYXRpb24ucHk= 100644
--- a/hgext3rd/heptapod/tests/git/test_integration.py
+++ b/hgext3rd/heptapod/tests/git/test_integration.py
@@ -16,6 +16,7 @@
 import pytest
 import re
 import shutil
+import subprocess
 
 from heptapod.gitlab import hooks
 from heptapod.gitlab.prune_reasons import (
@@ -154,9 +155,11 @@
     }
 
 
-def test_moved_out_of_gitaly_reach(main_fixture):
+@parametrize('pool', ('with-pool', 'without_pool'))
+def test_moved_out_of_gitaly_reach(main_fixture, pool):
+    with_pool = pool == 'with-pool'
     fixture = main_fixture
     wrapper = fixture.hg_repo_wrapper
     wrapper.command('gitlab-mirror')
     orig_git_path = fixture.git_repo.path
     assert fixture.git_repo.branch_titles() == {b'branch/default': b'default1'}
@@ -158,10 +161,26 @@
     fixture = main_fixture
     wrapper = fixture.hg_repo_wrapper
     wrapper.command('gitlab-mirror')
     orig_git_path = fixture.git_repo.path
     assert fixture.git_repo.branch_titles() == {b'branch/default': b'default1'}
+    alternates_relpath = 'objects/info/alternates'
+    if with_pool:
+        pools_path = orig_git_path / '../@pools'
+        pools_path.mkdir()
+        in_pool_path = pools_path / 'shared.git'
+        orig_git_path.rename(in_pool_path)
+        # git clone --shared normalizes the 'alternates' with absolute paths.
+        # There is now point trying to give it relative paths, we will
+        # edit the alternates later on to match what GitLab does
+        pool_rel_path = b'../../@pools/shared.git/objects'
+        subprocess.check_call(('git', 'clone', '--bare', '--shared',
+                               in_pool_path, orig_git_path))
+        (orig_git_path / alternates_relpath).write_binary(pool_rel_path)
+        # we did not break it by setting up the alternate objects store.
+        assert fixture.git_repo.branch_titles() == {
+            b'branch/default': b'default1'}
 
     wrapper.set_config('heptapod', 'native', True)
     fixture.reload_git_repo()
     assert fixture.git_repo.path != orig_git_path
 
@@ -163,11 +182,12 @@
 
     wrapper.set_config('heptapod', 'native', True)
     fixture.reload_git_repo()
     assert fixture.git_repo.path != orig_git_path
 
+    # this performs the move
     wrapper.commit_file('foo',
                         content='foo2',
                         message="default2")
     wrapper.command('gitlab-mirror')
     wrapper.command('hpd-export-native-to-git')
     assert fixture.git_repo.branch_titles() == {b'branch/default': b'default2'}
@@ -168,9 +188,21 @@
     wrapper.commit_file('foo',
                         content='foo2',
                         message="default2")
     wrapper.command('gitlab-mirror')
     wrapper.command('hpd-export-native-to-git')
     assert fixture.git_repo.branch_titles() == {b'branch/default': b'default2'}
+    # subsequent updates (not going through the moving code) also work
+    wrapper.commit_file('foo',
+                        content='foo3',
+                        message="default3")
+    wrapper.command('gitlab-mirror')
+    wrapper.command('hpd-export-native-to-git')
+    assert fixture.git_repo.branch_titles() == {b'branch/default': b'default3'}
+
+    if with_pool:
+        # just to be sure
+        assert (fixture.git_repo.path / alternates_relpath
+                ).read_binary() != pool_rel_path
 
 
 @parametrize('pushvar', ('skip-ci', 'mr-create'))