const char *refname,
struct dir_iterator *iter);
+static int files_fsck_symref_target(struct fsck_options *o,
+ struct fsck_ref_report *report,
+ struct strbuf *referent)
+{
+ char orig_last_byte;
+ size_t orig_len;
+ int ret = 0;
+
+ orig_len = referent->len;
+ orig_last_byte = referent->buf[orig_len - 1];
+ strbuf_rtrim(referent);
+
+ if (!is_root_ref(referent->buf) &&
+ check_refname_format(referent->buf, 0)) {
+ ret = fsck_report_ref(o, report,
+ FSCK_MSG_BAD_REFERENT_NAME,
+ "points to invalid refname '%s'", referent->buf);
+ goto out;
+ }
+
+ if (referent->len == orig_len ||
+ (referent->len < orig_len && orig_last_byte != '\n')) {
+ ret = fsck_report_ref(o, report,
+ FSCK_MSG_REF_MISSING_NEWLINE,
+ "misses LF at the end");
+ }
+
+ if (referent->len != orig_len && referent->len != orig_len - 1) {
+ ret = fsck_report_ref(o, report,
+ FSCK_MSG_TRAILING_REF_CONTENT,
+ "has trailing whitespaces or newlines");
+ }
+
+out:
+ return ret;
+}
+
static int files_fsck_refs_content(struct ref_store *ref_store,
struct fsck_options *o,
const char *target_name,
"has trailing garbage: '%s'", trailing);
goto cleanup;
}
+ } else {
+ ret = files_fsck_symref_target(o, &report, &referent);
+ goto cleanup;
}
cleanup:
test_cmp expect sorted_err
'
+test_expect_success 'textual symref content should be checked (individual)' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
+ branch_dir_prefix=.git/refs/heads &&
+ cd repo &&
+ test_commit default &&
+ mkdir -p "$branch_dir_prefix/a/b" &&
+
+ for good_referent in "refs/heads/branch" "HEAD"
+ do
+ printf "ref: %s\n" $good_referent >$branch_dir_prefix/branch-good &&
+ git refs verify 2>err &&
+ rm $branch_dir_prefix/branch-good &&
+ test_must_be_empty err || return 1
+ done &&
+
+ for bad_referent in "refs/heads/.branch" "refs/heads/~branch" "refs/heads/?branch"
+ do
+ printf "ref: %s\n" $bad_referent >$branch_dir_prefix/branch-bad &&
+ test_must_fail git refs verify 2>err &&
+ cat >expect <<-EOF &&
+ error: refs/heads/branch-bad: badReferentName: points to invalid refname '\''$bad_referent'\''
+ EOF
+ rm $branch_dir_prefix/branch-bad &&
+ test_cmp expect err || return 1
+ done &&
+
+ printf "ref: refs/heads/branch" >$branch_dir_prefix/branch-no-newline &&
+ git refs verify 2>err &&
+ cat >expect <<-EOF &&
+ warning: refs/heads/branch-no-newline: refMissingNewline: misses LF at the end
+ EOF
+ rm $branch_dir_prefix/branch-no-newline &&
+ test_cmp expect err &&
+
+ printf "ref: refs/heads/branch " >$branch_dir_prefix/a/b/branch-trailing-1 &&
+ git refs verify 2>err &&
+ cat >expect <<-EOF &&
+ warning: refs/heads/a/b/branch-trailing-1: refMissingNewline: misses LF at the end
+ warning: refs/heads/a/b/branch-trailing-1: trailingRefContent: has trailing whitespaces or newlines
+ EOF
+ rm $branch_dir_prefix/a/b/branch-trailing-1 &&
+ test_cmp expect err &&
+
+ printf "ref: refs/heads/branch\n\n" >$branch_dir_prefix/a/b/branch-trailing-2 &&
+ git refs verify 2>err &&
+ cat >expect <<-EOF &&
+ warning: refs/heads/a/b/branch-trailing-2: trailingRefContent: has trailing whitespaces or newlines
+ EOF
+ rm $branch_dir_prefix/a/b/branch-trailing-2 &&
+ test_cmp expect err &&
+
+ printf "ref: refs/heads/branch \n" >$branch_dir_prefix/a/b/branch-trailing-3 &&
+ git refs verify 2>err &&
+ cat >expect <<-EOF &&
+ warning: refs/heads/a/b/branch-trailing-3: trailingRefContent: has trailing whitespaces or newlines
+ EOF
+ rm $branch_dir_prefix/a/b/branch-trailing-3 &&
+ test_cmp expect err &&
+
+ printf "ref: refs/heads/branch \n " >$branch_dir_prefix/a/b/branch-complicated &&
+ git refs verify 2>err &&
+ cat >expect <<-EOF &&
+ warning: refs/heads/a/b/branch-complicated: refMissingNewline: misses LF at the end
+ warning: refs/heads/a/b/branch-complicated: trailingRefContent: has trailing whitespaces or newlines
+ EOF
+ rm $branch_dir_prefix/a/b/branch-complicated &&
+ test_cmp expect err
+'
+
+test_expect_success 'textual symref content should be checked (aggregate)' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
+ branch_dir_prefix=.git/refs/heads &&
+ tag_dir_prefix=.git/refs/tags &&
+ cd repo &&
+ test_commit default &&
+ mkdir -p "$branch_dir_prefix/a/b" &&
+
+ printf "ref: refs/heads/branch\n" >$branch_dir_prefix/branch-good &&
+ printf "ref: HEAD\n" >$branch_dir_prefix/branch-head &&
+ printf "ref: refs/heads/branch" >$branch_dir_prefix/branch-no-newline-1 &&
+ printf "ref: refs/heads/branch " >$branch_dir_prefix/a/b/branch-trailing-1 &&
+ printf "ref: refs/heads/branch\n\n" >$branch_dir_prefix/a/b/branch-trailing-2 &&
+ printf "ref: refs/heads/branch \n" >$branch_dir_prefix/a/b/branch-trailing-3 &&
+ printf "ref: refs/heads/branch \n " >$branch_dir_prefix/a/b/branch-complicated &&
+ printf "ref: refs/heads/.branch\n" >$branch_dir_prefix/branch-bad-1 &&
+
+ test_must_fail git refs verify 2>err &&
+ cat >expect <<-EOF &&
+ error: refs/heads/branch-bad-1: badReferentName: points to invalid refname '\''refs/heads/.branch'\''
+ warning: refs/heads/a/b/branch-complicated: refMissingNewline: misses LF at the end
+ warning: refs/heads/a/b/branch-complicated: trailingRefContent: has trailing whitespaces or newlines
+ warning: refs/heads/a/b/branch-trailing-1: refMissingNewline: misses LF at the end
+ warning: refs/heads/a/b/branch-trailing-1: trailingRefContent: has trailing whitespaces or newlines
+ warning: refs/heads/a/b/branch-trailing-2: trailingRefContent: has trailing whitespaces or newlines
+ warning: refs/heads/a/b/branch-trailing-3: trailingRefContent: has trailing whitespaces or newlines
+ warning: refs/heads/branch-no-newline-1: refMissingNewline: misses LF at the end
+ EOF
+ sort err >sorted_err &&
+ test_cmp expect sorted_err
+'
+
test_expect_success 'ref content checks should work with worktrees' '
test_when_finished "rm -rf repo" &&
git init repo &&
warning: worktrees/worktree-1/refs/worktree/branch-no-newline: refMissingNewline: misses LF at the end
EOF
rm $worktree1_refdir_prefix/branch-no-newline &&
+ test_cmp expect err &&
+
+ printf "%s garbage" "$(git rev-parse HEAD)" >$worktree1_refdir_prefix/branch-garbage &&
+ git refs verify 2>err &&
+ cat >expect <<-EOF &&
+ warning: worktrees/worktree-1/refs/worktree/branch-garbage: trailingRefContent: has trailing garbage: '\'' garbage'\''
+ EOF
+ rm $worktree1_refdir_prefix/branch-garbage &&
test_cmp expect err
'