diff --git a/submodule.c b/submodule.c
index c47358097fd..a464c99a27f 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2271,9 +2271,12 @@ int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
 static void relocate_single_git_dir_into_superproject(const char *path)
 {
 	char *old_git_dir = NULL, *real_old_git_dir = NULL, *real_new_git_dir = NULL;
+	char *rel_old_git_dir;
+	const char *rel_new_git_dir;
 	struct strbuf new_gitdir = STRBUF_INIT;
 	const struct submodule *sub;
-	size_t off = 0;
+	const char *super_prefix = get_super_prefix();
+	const char *sp = super_prefix ? super_prefix : "";
 
 	if (submodule_uses_worktrees(path))
 		die(_("relocate_gitdir for submodule '%s' with "
@@ -2285,6 +2288,7 @@ static void relocate_single_git_dir_into_superproject(const char *path)
 		return;
 
 	real_old_git_dir = real_pathdup(old_git_dir, 1);
+	rel_old_git_dir = xstrfmt("%s%s", sp, old_git_dir);
 
 	sub = submodule_from_path(the_repository, null_oid(), path);
 	if (!sub)
@@ -2293,23 +2297,23 @@ static void relocate_single_git_dir_into_superproject(const char *path)
 	submodule_name_to_gitdir(&new_gitdir, the_repository, sub->name);
 	if (validate_submodule_git_dir(new_gitdir.buf, sub->name) < 0)
 		die(_("refusing to move '%s' into an existing git dir"),
-		    real_old_git_dir);
+		    rel_old_git_dir);
 	if (safe_create_leading_directories_const(new_gitdir.buf) < 0)
 		die(_("could not create directory '%s'"), new_gitdir.buf);
+
 	real_new_git_dir = real_pathdup(new_gitdir.buf, 1);
+	rel_new_git_dir = relative_path(real_new_git_dir, real_old_git_dir,
+					&new_gitdir);
 
-	while (real_old_git_dir[off] && real_new_git_dir[off] &&
-	       real_old_git_dir[off] == real_new_git_dir[off])
-		off++;
 	fprintf(stderr, _("Migrating git directory of '%s%s' from '%s' to '%s'\n"),
-		get_super_prefix_or_empty(), path,
-		real_old_git_dir + off, real_new_git_dir + off);
+		sp, path, rel_old_git_dir, rel_new_git_dir);
 
 	relocate_gitdir(path, real_old_git_dir, real_new_git_dir);
 
 	free(old_git_dir);
 	free(real_old_git_dir);
 	free(real_new_git_dir);
+	free(rel_old_git_dir);
 	strbuf_release(&new_gitdir);
 }
 
diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
index a5cd6db7ac2..0afa0fe3a83 100755
--- a/t/t7412-submodule-absorbgitdirs.sh
+++ b/t/t7412-submodule-absorbgitdirs.sh
@@ -27,7 +27,7 @@ test_expect_success 'absorb the git dir' '
 	git status >expect.1 &&
 	git -C sub1 rev-parse HEAD >expect.2 &&
 	cat >expect <<-\EOF &&
-	Migrating git directory of '\''sub1'\'' from '\''sub1/.git'\'' to '\''.git/modules/sub1'\''
+	Migrating git directory of '\''sub1'\'' from '\''sub1/.git'\'' to '\''../../.git/modules/sub1'\''
 	EOF
 	git submodule absorbgitdirs 2>actual &&
 	test_cmp expect actual &&
@@ -64,7 +64,7 @@ test_expect_success 'absorb the git dir in a nested submodule' '
 	git status >expect.1 &&
 	git -C sub1/nested rev-parse HEAD >expect.2 &&
 	cat >expect <<-\EOF &&
-	Migrating git directory of '\''sub1/nested'\'' from '\''sub1/nested/.git'\'' to '\''.git/modules/sub1/modules/nested'\''
+	Migrating git directory of '\''sub1/nested'\'' from '\''sub1/nested/.git'\'' to '\''../../../.git/modules/sub1/modules/nested'\''
 	EOF
 	git submodule absorbgitdirs 2>actual &&
 	test_cmp expect actual &&
@@ -99,7 +99,7 @@ test_expect_success 'absorb the git dir in a nested submodule' '
 	git status >expect.1 &&
 	git -C sub1/nested rev-parse HEAD >expect.2 &&
 	cat >expect <<-\EOF &&
-	Migrating git directory of '\''sub1'\'' from '\''sub1/.git'\'' to '\''.git/modules/sub1'\''
+	Migrating git directory of '\''sub1'\'' from '\''sub1/.git'\'' to '\''../../.git/modules/sub1'\''
 	EOF
 	git submodule absorbgitdirs 2>actual &&
 	test_cmp expect actual &&
@@ -112,6 +112,25 @@ test_expect_success 'absorb the git dir in a nested submodule' '
 	test_cmp expect.2 actual.2
 '
 
+test_expect_success 'absorb the git dir outside of primary worktree' '
+	test_when_finished "rm -rf repo-bare.git" &&
+	git clone --bare . repo-bare.git &&
+	test_when_finished "rm -rf repo-wt" &&
+	git -C repo-bare.git worktree add ../repo-wt &&
+
+	test_when_finished "rm -f .gitconfig" &&
+	test_config_global protocol.file.allow always &&
+	git -C repo-wt submodule update --init &&
+	git init repo-wt/sub2 &&
+	test_commit -C repo-wt/sub2 A &&
+	git -C repo-wt submodule add ./sub2 sub2 &&
+	cat >expect <<-EOF &&
+	Migrating git directory of '\''sub2'\'' from '\''sub2/.git'\'' to '\''../../../repo-bare.git/worktrees/repo-wt/modules/sub2'\''
+	EOF
+	DO_IT=1 git -C repo-wt submodule absorbgitdirs 2>actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'setup a gitlink with missing .gitmodules entry' '
 	git init sub2 &&
 	test_commit -C sub2 first &&
