Subject: [PATCH v5 7/9] ref: enhance escape situation for worktrees

From: shejialuo <[email-masked]>
Date: Sun, 29 Sep 2024 15:17:01 +0800

We do allow users to use "git symbolic-ref" to create symrefs which
point to one of the linked worktrees from the primary worktree or one of
the linked worktrees.

We should not info the user about the escape for above situation. So,
enhance "files_fsck_symref_target" function to check whether the "referent"
starts with the "worktrees/" to make sure that we won't warn the user
when symrefs point to "referent" in the linked worktrees.

Mentored-by: Patrick Steinhardt <[email-masked]>
Mentored-by: Karthik Nayak <[email-masked]>
Signed-off-by: shejialuo <[email-masked]>
---
 refs/files-backend.c     |  5 +++--
 t/t0602-reffiles-fsck.sh | 34 +++++++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/refs/files-backend.c b/refs/files-backend.c
index bd215c8d08..1182bca108 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -3520,10 +3520,11 @@ static int files_fsck_symref_target(struct fsck_options *o,
 	orig_last_byte = referent->buf[orig_len - 1];
 	strbuf_rtrim(referent);
 
-	if (!starts_with(referent->buf, "refs/")) {
+	if (!starts_with(referent->buf, "refs/") &&
+	    !starts_with(referent->buf, "worktrees/")) {
 		ret = fsck_report_ref(o, report,
 				      FSCK_MSG_ESCAPE_REFERENT,
-				      "referent '%s' is outside of refs/",
+				      "referent '%s' is outside of refs/ or worktrees/",
 				      referent->buf);
 	}
 
diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh
index 585f562245..936448f780 100755
--- a/t/t0602-reffiles-fsck.sh
+++ b/t/t0602-reffiles-fsck.sh
@@ -382,10 +382,42 @@ test_expect_success 'textual symref should be checked whether it is escaped' '
 	printf "ref: refs-back/heads/main\n" >$branch_dir_prefix/branch-bad-1 &&
 	git refs verify 2>err &&
 	cat >expect <<-EOF &&
-	warning: refs/heads/branch-bad-1: escapeReferent: referent '\''refs-back/heads/main'\'' is outside of refs/
+	warning: refs/heads/branch-bad-1: escapeReferent: referent '\''refs-back/heads/main'\'' is outside of refs/ or worktrees/
 	EOF
 	rm $branch_dir_prefix/branch-bad-1 &&
 	test_cmp expect err
 '
 
+test_expect_success 'textual symref escape check should work with worktrees' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	cd repo &&
+	test_commit default &&
+	git branch branch-1 &&
+	git branch branch-2 &&
+	git branch branch-3 &&
+	git worktree add ./worktree-1 branch-2 &&
+	git worktree add ./worktree-2 branch-3 &&
+
+	(
+		cd worktree-1 &&
+		git branch refs/worktree/w1-branch &&
+		git symbolic-ref refs/worktree/branch-4 refs/heads/branch-1 &&
+		git symbolic-ref refs/worktree/branch-5 worktrees/worktree-2/refs/worktree/w2-branch
+	) &&
+	(
+		cd worktree-2 &&
+		git branch refs/worktree/w2-branch &&
+		git symbolic-ref refs/worktree/branch-4 refs/heads/branch-1 &&
+		git symbolic-ref refs/worktree/branch-5 worktrees/worktree-1/refs/worktree/w1-branch
+	) &&
+
+
+	git symbolic-ref refs/heads/branch-5 worktrees/worktree-1/refs/worktree/w1-branch &&
+	git symbolic-ref refs/heads/branch-6 worktrees/worktree-2/refs/worktree/w2-branch &&
+
+	git refs verify 2>err &&
+	test_must_be_empty err
+'
+
 test_done
-- 
2.46.2