Skip to content

Commit 57e81b5

Browse files
committed
Merge branch 'sj/ref-contents-check'
"git fsck" learned to issue warnings on "curiously formatted" ref contents that have always been taken valid but something Git wouldn't have written itself (e.g., missing terminating end-of-line after the full object name). * sj/ref-contents-check: ref: add symlink ref content check for files backend ref: check whether the target of the symref is a ref ref: add basic symref content check for files backend ref: add more strict checks for regular refs ref: port git-fsck(1) regular refs check for files backend ref: support multiple worktrees check for refs ref: initialize ref name outside of check functions ref: check the full refname instead of basename ref: initialize "fsck_ref_report" with zero
2 parents 7ee055b + c9f03f3 commit 57e81b5

File tree

11 files changed

+790
-62
lines changed

11 files changed

+790
-62
lines changed

Documentation/fsck-msgids.txt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,18 @@
1919
`badParentSha1`::
2020
(ERROR) A commit object has a bad parent sha1.
2121

22+
`badRefContent`::
23+
(ERROR) A ref has bad content.
24+
2225
`badRefFiletype`::
2326
(ERROR) A ref has a bad file type.
2427

2528
`badRefName`::
2629
(ERROR) A ref has an invalid format.
2730

31+
`badReferentName`::
32+
(ERROR) The referent name of a symref is invalid.
33+
2834
`badTagName`::
2935
(INFO) A tag has an invalid format.
3036

@@ -170,6 +176,35 @@
170176
`nullSha1`::
171177
(WARN) Tree contains entries pointing to a null sha1.
172178

179+
`refMissingNewline`::
180+
(INFO) A loose ref that does not end with newline(LF). As
181+
valid implementations of Git never created such a loose ref
182+
file, it may become an error in the future. Report to the
183+
[email protected] mailing list if you see this error, as
184+
we need to know what tools created such a file.
185+
186+
`symlinkRef`::
187+
(INFO) A symbolic link is used as a symref. Report to the
188+
[email protected] mailing list if you see this error, as we
189+
are assessing the feasibility of dropping the support to drop
190+
creating symbolic links as symrefs.
191+
192+
`symrefTargetIsNotARef`::
193+
(INFO) The target of a symbolic reference points neither to
194+
a root reference nor to a reference starting with "refs/".
195+
Although we allow create a symref pointing to the referent which
196+
is outside the "ref" by using `git symbolic-ref`, we may tighten
197+
the rule in the future. Report to the [email protected]
198+
mailing list if you see this error, as we need to know what tools
199+
created such a file.
200+
201+
`trailingRefContent`::
202+
(INFO) A loose ref has trailing content. As valid implementations
203+
of Git never created such a loose ref file, it may become an
204+
error in the future. Report to the [email protected] mailing
205+
list if you see this error, as we need to know what tools
206+
created such a file.
207+
173208
`treeNotSorted`::
174209
(ERROR) A tree is not properly sorted.
175210

builtin/refs.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "parse-options.h"
66
#include "refs.h"
77
#include "strbuf.h"
8+
#include "worktree.h"
89

910
#define REFS_MIGRATE_USAGE \
1011
N_("git refs migrate --ref-format=<format> [--dry-run]")
@@ -66,6 +67,7 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)
6667
static int cmd_refs_verify(int argc, const char **argv, const char *prefix)
6768
{
6869
struct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT;
70+
struct worktree **worktrees;
6971
const char * const verify_usage[] = {
7072
REFS_VERIFY_USAGE,
7173
NULL,
@@ -75,7 +77,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix)
7577
OPT_BOOL(0, "strict", &fsck_refs_options.strict, N_("enable strict checking")),
7678
OPT_END(),
7779
};
78-
int ret;
80+
int ret = 0;
7981

8082
argc = parse_options(argc, argv, prefix, options, verify_usage, 0);
8183
if (argc)
@@ -84,9 +86,13 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix)
8486
git_config(git_fsck_config, &fsck_refs_options);
8587
prepare_repo_settings(the_repository);
8688

87-
ret = refs_fsck(get_main_ref_store(the_repository), &fsck_refs_options);
89+
worktrees = get_worktrees();
90+
for (size_t i = 0; worktrees[i]; i++)
91+
ret |= refs_fsck(get_worktree_ref_store(worktrees[i]),
92+
&fsck_refs_options, worktrees[i]);
8893

8994
fsck_options_clear(&fsck_refs_options);
95+
free_worktrees(worktrees);
9096
return ret;
9197
}
9298

fsck.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ enum fsck_msg_type {
3131
FUNC(BAD_NAME, ERROR) \
3232
FUNC(BAD_OBJECT_SHA1, ERROR) \
3333
FUNC(BAD_PARENT_SHA1, ERROR) \
34+
FUNC(BAD_REF_CONTENT, ERROR) \
3435
FUNC(BAD_REF_FILETYPE, ERROR) \
3536
FUNC(BAD_REF_NAME, ERROR) \
37+
FUNC(BAD_REFERENT_NAME, ERROR) \
3638
FUNC(BAD_TIMEZONE, ERROR) \
3739
FUNC(BAD_TREE, ERROR) \
3840
FUNC(BAD_TREE_SHA1, ERROR) \
@@ -84,6 +86,10 @@ enum fsck_msg_type {
8486
FUNC(MAILMAP_SYMLINK, INFO) \
8587
FUNC(BAD_TAG_NAME, INFO) \
8688
FUNC(MISSING_TAGGER_ENTRY, INFO) \
89+
FUNC(SYMLINK_REF, INFO) \
90+
FUNC(REF_MISSING_NEWLINE, INFO) \
91+
FUNC(SYMREF_TARGET_IS_NOT_A_REF, INFO) \
92+
FUNC(TRAILING_REF_CONTENT, INFO) \
8793
/* ignored (elevated when requested) */ \
8894
FUNC(EXTRA_HEADER_ENTRY, IGNORE)
8995

refs.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,10 @@ int check_refname_format(const char *refname, int flags)
318318
return check_or_sanitize_refname(refname, flags, NULL);
319319
}
320320

321-
int refs_fsck(struct ref_store *refs, struct fsck_options *o)
321+
int refs_fsck(struct ref_store *refs, struct fsck_options *o,
322+
struct worktree *wt)
322323
{
323-
return refs->be->fsck(refs, o);
324+
return refs->be->fsck(refs, o, wt);
324325
}
325326

326327
void sanitize_refname_component(const char *refname, struct strbuf *out)
@@ -1791,7 +1792,7 @@ static int refs_read_special_head(struct ref_store *ref_store,
17911792
}
17921793

17931794
result = parse_loose_ref_contents(ref_store->repo->hash_algo, content.buf,
1794-
oid, referent, type, failure_errno);
1795+
oid, referent, type, NULL, failure_errno);
17951796

17961797
done:
17971798
strbuf_release(&full_path);

refs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,8 @@ int check_refname_format(const char *refname, int flags);
550550
* reflogs are consistent, and non-zero otherwise. The errors will be
551551
* written to stderr.
552552
*/
553-
int refs_fsck(struct ref_store *refs, struct fsck_options *o);
553+
int refs_fsck(struct ref_store *refs, struct fsck_options *o,
554+
struct worktree *wt);
554555

555556
/*
556557
* Apply the rules from check_refname_format, but mutate the result until it

refs/debug.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,11 @@ static int debug_reflog_expire(struct ref_store *ref_store, const char *refname,
408408
}
409409

410410
static int debug_fsck(struct ref_store *ref_store,
411-
struct fsck_options *o)
411+
struct fsck_options *o,
412+
struct worktree *wt)
412413
{
413414
struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
414-
int res = drefs->refs->be->fsck(drefs->refs, o);
415+
int res = drefs->refs->be->fsck(drefs->refs, o, wt);
415416
trace_printf_key(&trace_refs, "fsck: %d\n", res);
416417
return res;
417418
}

0 commit comments

Comments
 (0)