Subject: [PATCH v6 0/9] add more ref consistency checks

From: shejialuo <[email-masked]>
Date: Tue, 25 Feb 2025 21:19:11 +0800

Hi All:

This changes enhances the following things (v6-changed):

1. [PATCH v6 2/9]: enhance the comment.
2. [PATCH v6 3/9]: use '' to quote the file in the print message.
2. [PATCH v6 4/9]: a new commit message to explain why we can tighten
the rule.

Thanks,
Jialuo

---

This series mainly does the following things:

1. Fix subshell issues
2. Add ref checks for packed-backend.
   1. Check whether the filetype of "packed-refs" is correct.
   2. Check whether the syntax of "packed-refs" is correct by using the
      rules from "packed-backend.c::create_snapshot" and
      "packed-backend.c::next_record".
   3. Check whether the pointed object exists and whether the
      "packed-refs" file is sorted.
3. Call "git refs verify" for "git-fsck(1)".

shejialuo (9):
  t0602: use subshell to ensure working directory unchanged
  builtin/refs: get worktrees without reading head information
  packed-backend: check whether the "packed-refs" is regular file
  packed-backend: check if header starts with "# pack-refs with: "
  packed-backend: add "packed-refs" header consistency check
  packed-backend: check whether the refname contains NUL characters
  packed-backend: add "packed-refs" entry consistency check
  packed-backend: check whether the "packed-refs" is sorted
  builtin/fsck: add `git refs verify` child process

 Documentation/fsck-msgids.adoc |   14 +
 Documentation/git-fsck.adoc    |    7 +-
 builtin/fsck.c                 |   33 +-
 builtin/refs.c                 |    2 +-
 fsck.h                         |    4 +
 refs/packed-backend.c          |  369 +++++++++-
 t/t0602-reffiles-fsck.sh       | 1205 +++++++++++++++++++-------------
 worktree.c                     |    5 +
 worktree.h                     |    8 +
 9 files changed, 1162 insertions(+), 485 deletions(-)

Range-diff against v5:
 1:  b3952d80a2 =  1:  b3952d80a2 t0602: use subshell to ensure working directory unchanged
 2:  3695586f58 !  2:  fa5ce20bb7 builtin/refs: get worktrees without reading head information
    @@ worktree.h: struct worktree {
     +/*
     + * Like `get_worktrees`, but does not read HEAD. Skip reading HEAD allows to
     + * get the worktree without worrying about failures pertaining to parsing
    -+ * the HEAD ref. This is useful when we want to check the ref db consistency.
    ++ * the HEAD ref. This is useful in contexts where it is assumed that the
    ++ * refdb may not be in a consistent state.
     + */
     +struct worktree **get_worktrees_without_reading_head(void);
     +
 3:  cbaae00e8b !  3:  787645a700 packed-backend: check whether the "packed-refs" is regular file
    @@ refs/packed-backend.c: static struct ref_iterator *packed_reflog_iterator_begin(
     +		 */
     +		if (errno == ENOENT)
     +			goto cleanup;
    -+		ret = error_errno(_("unable to stat %s"), refs->path);
    ++		ret = error_errno(_("unable to stat '%s'"), refs->path);
     +		goto cleanup;
     +	}
     +
 -:  ---------- >  4:  f097e0f093 packed-backend: check if header starts with "# pack-refs with: "
 4:  b9ce8734ac !  5:  a589a38b68 packed-backend: add "packed-refs" header consistency check
    @@ Commit message
     
         In "packed-backend.c::create_snapshot", if there is a header (the line
         which starts with '#'), we will check whether the line starts with "#
    -    pack-refs with:". Before we port this check into "packed_fsck", let's
    -    fix "create_snapshot" to check the prefix "# packed-ref with: " instead
    -    of "# packed-ref with:" due to that we will always write a single
    -    trailing space after the colon.
    -
    -    However, we need to consider other situations and discuss whether we
    -    need to add checks.
    +    pack-refs with: ". However, we need to consider other situations and
    +    discuss whether we need to add checks.
     
         1. If the header does not exist, we should not report an error to the
            user. This is because in older Git version, we never write header in
    @@ fsck.h: enum fsck_msg_type {
      	FUNC(ZERO_PADDED_DATE, ERROR) \
     
      ## refs/packed-backend.c ##
    -@@ refs/packed-backend.c: static struct snapshot *create_snapshot(struct packed_ref_store *refs)
    - 
    - 		tmp = xmemdupz(snapshot->buf, eol - snapshot->buf);
    - 
    --		if (!skip_prefix(tmp, "# pack-refs with:", (const char **)&p))
    -+		if (!skip_prefix(tmp, "# pack-refs with: ", (const char **)&p))
    - 			die_invalid_line(refs->path,
    - 					 snapshot->buf,
    - 					 snapshot->eof - snapshot->buf);
     @@ refs/packed-backend.c: static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_s
      	return empty_ref_iterator_begin();
      }
 5:  9f638b3adf =  6:  7255c2b597 packed-backend: check whether the refname contains NUL characters
 6:  2c5395bdd0 =  7:  7794a2ebfd packed-backend: add "packed-refs" entry consistency check
 7:  648404c60d =  8:  2a9138b14d packed-backend: check whether the "packed-refs" is sorted
 8:  4dbbacf44b =  9:  ccde32491f builtin/fsck: add `git refs verify` child process
-- 
2.48.1