public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
From: shejialuo <shejialuo@gmail.com>
To: Patrick Steinhardt <ps@pks.im>
Cc: git@vger.kernel.org, Karthik Nayak <karthik.188@gmail.com>
Subject: Re: [PATCH 09/17] refs/files: extract generic symref target checks
Date: Sat, 10 Jan 2026 20:59:10 +0800	[thread overview]
Message-ID: <aWJNHgFnimXRHkb6@ArchLinux> (raw)
In-Reply-To: <20260109-pks-refs-verify-fixes-v1-9-3587dba18294@pks.im>

On Fri, Jan 09, 2026 at 01:39:38PM +0100, Patrick Steinhardt wrote:
> The consistency checks for the "files" backend contain a couple of
> verifications for symrefs that verify generic properties of the target
> reference. These properties need to hold for every backend, no matter
> whether it's using the "files" or "reftable" backend.
> 
> Reimplementing these checks for every single backend doesn't really make
> sense. Extract it into a generic `refs_fsck_symref()` function that can
> be used my other backends, as well. The "reftable" backend will be wired
> up in a subsequent commit.
> 

s/my/by

> While at it, improve the consistency checks so that we don't complain
> about refs pointing to a non-ref target in case the target refname
> format does not verify. Otherwise it's very likely that we'll generate
> both error messages, which feels somewhat redundant in this case.
> 

Make sense, we should fail early in this case.

> Note that the function has a couple of `UNUSED` parameters. These will
> become referenced in a subsequent commit.
> 
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
>  refs.c               | 21 ++++++++++++++++++++
>  refs.h               | 10 ++++++++++
>  refs/files-backend.c | 54 ++++++++++++++++++++--------------------------------
>  3 files changed, 52 insertions(+), 33 deletions(-)
> 
> diff --git a/refs.c b/refs.c
> index e06e0cb072..739bf9fefc 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -320,6 +320,27 @@ int check_refname_format(const char *refname, int flags)
>  	return check_or_sanitize_refname(refname, flags, NULL);
>  }
>  
> +int refs_fsck_symref(struct ref_store *refs UNUSED, struct fsck_options *o,
> +		     struct fsck_ref_report *report,
> +		     const char *refname UNUSED, const char *target)
> +{
> +	if (is_root_ref(target))
> +		return 0;
> +
> +	if (check_refname_format(target, 0) &&
> +	    fsck_report_ref(o, report, FSCK_MSG_BAD_REFERENT_NAME,
> +			    "points to invalid refname '%s'", target))
> +		return -1;
> +
> +	if (!starts_with(target, "refs/") &&
> +	    !starts_with(target, "worktrees/") &&
> +	    fsck_report_ref(o, report, FSCK_MSG_SYMREF_TARGET_IS_NOT_A_REF,
> +			    "points to non-ref target '%s'", target))
> +		return -1;
> +
> +	return 0;
> +}
> +
>  int refs_fsck(struct ref_store *refs, struct fsck_options *o,
>  	      struct worktree *wt)
>  {
> diff --git a/refs.h b/refs.h
> index d9051bbb04..d91fcb2d2f 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -653,6 +653,16 @@ int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_dat
>   */
>  int check_refname_format(const char *refname, int flags);
>  
> +struct fsck_ref_report;
> +
> +/*
> + * Perform generic checks for a specific symref target. This function is
> + * expected to be called by the ref backends for every symbolic ref.
> + */
> +int refs_fsck_symref(struct ref_store *refs, struct fsck_options *o,
> +		     struct fsck_ref_report *report,
> +		     const char *refname, const char *target);
> +
>  /*
>   * Check the reference database for consistency. Return 0 if refs and
>   * reflogs are consistent, and non-zero otherwise. The errors will be
> diff --git a/refs/files-backend.c b/refs/files-backend.c
> index 0ff047d0df..72c1db849e 100644
> --- a/refs/files-backend.c
> +++ b/refs/files-backend.c
> @@ -3718,53 +3718,39 @@ typedef int (*files_fsck_refs_fn)(struct ref_store *ref_store,
>  				  const char *path,
>  				  int mode);
>  
> -static int files_fsck_symref_target(struct fsck_options *o,
> +static int files_fsck_symref_target(struct ref_store *ref_store,
> +				    struct fsck_options *o,
>  				    struct fsck_ref_report *report,
> +				    const char *refname,
>  				    struct strbuf *referent,
>  				    unsigned int symbolic_link)


Nit: as we touch this function, maybe we could change `unsigned int
symbolic_link` to be `bool symbolic_link`.

>  {
> -	int is_referent_root;
>  	char orig_last_byte;
>  	size_t orig_len;
>  	int ret = 0;
>  
>  	orig_len = referent->len;
>  	orig_last_byte = referent->buf[orig_len - 1];
> -	if (!symbolic_link)
> -		strbuf_rtrim(referent);
> -
> -	is_referent_root = is_root_ref(referent->buf);
> -	if (!is_referent_root &&
> -	    !starts_with(referent->buf, "refs/") &&
> -	    !starts_with(referent->buf, "worktrees/")) {
> -		ret |= fsck_report_ref(o, report,
> -				       FSCK_MSG_SYMREF_TARGET_IS_NOT_A_REF,
> -				       "points to non-ref target '%s'", referent->buf);
> -	}
>  
> -	if (!is_referent_root && check_refname_format(referent->buf, 0)) {
> -		ret |= fsck_report_ref(o, report,
> -				       FSCK_MSG_BAD_REFERENT_NAME,
> -				       "points to invalid refname '%s'", referent->buf);
> -	}
> +	if (!symbolic_link) {
> +		strbuf_rtrim(referent);
>  
> -	if (symbolic_link)
> -		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 && 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");
> +		}
>  	}
>  
> -	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");
> -	}
> +	ret |= refs_fsck_symref(ref_store, o, report, refname, referent->buf);
>  
> -out:
>  	return ret ? -1 : 0;
>  }
>  
> @@ -3807,7 +3793,8 @@ static int files_fsck_refs_content(struct ref_store *ref_store,
>  		else
>  			strbuf_addbuf(&referent, &ref_content);
>  
> -		ret |= files_fsck_symref_target(o, &report, &referent, 1);
> +		ret |= files_fsck_symref_target(ref_store, o, &report,
> +						target_name, &referent, 1);

Nit: we might change 1 to be `true`.

>  		goto cleanup;
>  	}
>  
> @@ -3847,7 +3834,8 @@ static int files_fsck_refs_content(struct ref_store *ref_store,
>  			goto cleanup;
>  		}
>  	} else {
> -		ret = files_fsck_symref_target(o, &report, &referent, 0);
> +		ret = files_fsck_symref_target(ref_store, o, &report,
> +					       target_name, &referent, 0);
>  		goto cleanup;
>  	}
>  
> 
> -- 
> 2.52.0.542.g9473a8513b.dirty
> 

Thanks,
Jialuo

  reply	other threads:[~2026-01-10 12:59 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-09 12:39 [PATCH 00/17] Fixes and improvements for ref consistency checks Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 01/17] refs/files: simplify iterating through root refs Patrick Steinhardt
2026-01-10 12:28   ` shejialuo
2026-01-09 12:39 ` [PATCH 02/17] refs/files: move fsck functions into global scope Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 03/17] refs/files: remove `refs_check_dir` parameter Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 04/17] refs/files: remove useless indirection Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 05/17] refs/files: extract function to check single ref Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 06/17] refs/files: improve error handling when verifying symrefs Patrick Steinhardt
2026-01-10 12:34   ` shejialuo
2026-01-09 12:39 ` [PATCH 07/17] refs/files: perform consistency checks for root refs Patrick Steinhardt
2026-01-10 12:47   ` shejialuo
2026-01-12  8:17     ` Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 08/17] fsck: drop unused fields from `struct fsck_ref_report` Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 09/17] refs/files: extract generic symref target checks Patrick Steinhardt
2026-01-10 12:59   ` shejialuo [this message]
2026-01-12  8:17     ` Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 10/17] refs/files: introduce function to perform normal ref checks Patrick Steinhardt
2026-01-10 13:12   ` shejialuo
2026-01-12  8:17     ` Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 11/17] refs/reftable: adapt includes to become consistent Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 12/17] refs/reftable: extract function to retrieve backend for worktree Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 13/17] refs/reftable: fix consistency checks with worktrees Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 14/17] refs/reftable: introduce generic checks for refs Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 15/17] builtin/fsck: move generic object ID checks into `refs_fsck()` Patrick Steinhardt
2026-01-09 12:39 ` [PATCH 16/17] builtin/fsck: move generic HEAD check " Patrick Steinhardt
2026-01-10 13:31   ` shejialuo
2026-01-12  8:18     ` Patrick Steinhardt
2026-01-15 12:52       ` shejialuo
2026-01-09 12:39 ` [PATCH 17/17] builtin/fsck: drop `fsck_head_link()` Patrick Steinhardt
2026-01-10 13:37 ` [PATCH 00/17] Fixes and improvements for ref consistency checks shejialuo
2026-01-12  8:18   ` Patrick Steinhardt
2026-01-12  9:02 ` [PATCH v2 " Patrick Steinhardt
2026-01-12  9:02   ` [PATCH v2 01/17] refs/files: simplify iterating through root refs Patrick Steinhardt
2026-01-12  9:56     ` Karthik Nayak
2026-01-12  9:02   ` [PATCH v2 02/17] refs/files: move fsck functions into global scope Patrick Steinhardt
2026-01-12  9:02   ` [PATCH v2 03/17] refs/files: remove `refs_check_dir` parameter Patrick Steinhardt
2026-01-12  9:02   ` [PATCH v2 04/17] refs/files: remove useless indirection Patrick Steinhardt
2026-01-12 10:01     ` Karthik Nayak
2026-01-12  9:02   ` [PATCH v2 05/17] refs/files: extract function to check single ref Patrick Steinhardt
2026-01-12  9:02   ` [PATCH v2 06/17] refs/files: improve error handling when verifying symrefs Patrick Steinhardt
2026-01-12  9:02   ` [PATCH v2 07/17] refs/files: perform consistency checks for root refs Patrick Steinhardt
2026-01-12  9:02   ` [PATCH v2 08/17] fsck: drop unused fields from `struct fsck_ref_report` Patrick Steinhardt
2026-01-12  9:02   ` [PATCH v2 09/17] refs/files: extract generic symref target checks Patrick Steinhardt
2026-01-12  9:02   ` [PATCH v2 10/17] refs/files: introduce function to perform normal ref checks Patrick Steinhardt
2026-01-12 11:42     ` Karthik Nayak
2026-01-12 13:08       ` Patrick Steinhardt
2026-01-12 14:19         ` Junio C Hamano
2026-01-12 14:37           ` Junio C Hamano
2026-01-12 15:02             ` Patrick Steinhardt
2026-01-12  9:03   ` [PATCH v2 11/17] refs/reftable: adapt includes to become consistent Patrick Steinhardt
2026-01-12  9:03   ` [PATCH v2 12/17] refs/reftable: extract function to retrieve backend for worktree Patrick Steinhardt
2026-01-12  9:03   ` [PATCH v2 13/17] refs/reftable: fix consistency checks with worktrees Patrick Steinhardt
2026-01-12 11:45     ` Karthik Nayak
2026-01-12  9:03   ` [PATCH v2 14/17] refs/reftable: introduce generic checks for refs Patrick Steinhardt
2026-01-12  9:03   ` [PATCH v2 15/17] builtin/fsck: move generic object ID checks into `refs_fsck()` Patrick Steinhardt
2026-01-12  9:03   ` [PATCH v2 16/17] builtin/fsck: move generic HEAD check " Patrick Steinhardt
2026-01-12  9:03   ` [PATCH v2 17/17] builtin/fsck: drop `fsck_head_link()` Patrick Steinhardt
2026-01-12 11:50   ` [PATCH v2 00/17] Fixes and improvements for ref consistency checks Karthik Nayak
2026-01-12 13:09     ` Patrick Steinhardt
2026-01-15 12:56   ` shejialuo
2026-01-16  6:48     ` Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aWJNHgFnimXRHkb6@ArchLinux \
    --to=shejialuo@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=karthik.188@gmail.com \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox