2008-02-25 21:46:04 +00:00
|
|
|
#ifndef GIT_FSCK_H
|
|
|
|
#define GIT_FSCK_H
|
|
|
|
|
2018-09-03 14:49:27 +00:00
|
|
|
#include "oidset.h"
|
|
|
|
|
2008-02-25 21:46:08 +00:00
|
|
|
#define FSCK_ERROR 1
|
|
|
|
#define FSCK_WARN 2
|
2015-06-22 15:26:48 +00:00
|
|
|
#define FSCK_IGNORE 3
|
2008-02-25 21:46:08 +00:00
|
|
|
|
2015-06-22 15:25:00 +00:00
|
|
|
struct fsck_options;
|
2018-08-15 17:54:05 +00:00
|
|
|
struct object;
|
2015-06-22 15:25:00 +00:00
|
|
|
|
2015-06-22 15:25:25 +00:00
|
|
|
void fsck_set_msg_type(struct fsck_options *options,
|
|
|
|
const char *msg_id, const char *msg_type);
|
|
|
|
void fsck_set_msg_types(struct fsck_options *options, const char *values);
|
2015-06-22 15:25:31 +00:00
|
|
|
int is_valid_msg_type(const char *msg_id, const char *msg_type);
|
2015-06-22 15:25:25 +00:00
|
|
|
|
2008-02-25 21:46:04 +00:00
|
|
|
/*
|
|
|
|
* callback function for fsck_walk
|
|
|
|
* type is the expected type of the object or OBJ_ANY
|
|
|
|
* the return value is:
|
|
|
|
* 0 everything OK
|
|
|
|
* <0 error signaled and abort
|
|
|
|
* >0 error signaled and do not abort
|
|
|
|
*/
|
2015-06-22 15:25:00 +00:00
|
|
|
typedef int (*fsck_walk_func)(struct object *obj, int type, void *data, struct fsck_options *options);
|
2008-02-25 21:46:04 +00:00
|
|
|
|
2008-02-25 21:46:08 +00:00
|
|
|
/* callback for fsck_object, type is FSCK_ERROR or FSCK_WARN */
|
2016-07-17 10:59:57 +00:00
|
|
|
typedef int (*fsck_error)(struct fsck_options *o,
|
2019-10-18 04:58:40 +00:00
|
|
|
const struct object_id *oid, enum object_type object_type,
|
|
|
|
int msg_type, const char *message);
|
2008-02-25 21:46:08 +00:00
|
|
|
|
2016-07-17 10:59:57 +00:00
|
|
|
int fsck_error_function(struct fsck_options *o,
|
2019-10-18 04:58:40 +00:00
|
|
|
const struct object_id *oid, enum object_type object_type,
|
|
|
|
int msg_type, const char *message);
|
2008-02-25 21:46:09 +00:00
|
|
|
|
2015-06-22 15:25:00 +00:00
|
|
|
struct fsck_options {
|
|
|
|
fsck_walk_func walk;
|
|
|
|
fsck_error error_func;
|
|
|
|
unsigned strict:1;
|
2015-06-22 15:25:25 +00:00
|
|
|
int *msg_type;
|
2018-09-03 14:49:27 +00:00
|
|
|
struct oidset skiplist;
|
2019-10-18 04:57:37 +00:00
|
|
|
kh_oid_map_t *object_names;
|
2015-06-22 15:25:00 +00:00
|
|
|
};
|
|
|
|
|
2018-09-03 14:49:27 +00:00
|
|
|
#define FSCK_OPTIONS_DEFAULT { NULL, fsck_error_function, 0, NULL, OIDSET_INIT }
|
|
|
|
#define FSCK_OPTIONS_STRICT { NULL, fsck_error_function, 1, NULL, OIDSET_INIT }
|
2015-06-22 15:25:00 +00:00
|
|
|
|
2008-02-25 21:46:04 +00:00
|
|
|
/* descend in all linked child objects
|
|
|
|
* the return value is:
|
|
|
|
* -1 error in processing the object
|
|
|
|
* <0 return value of the callback, which lead to an abort
|
2009-04-17 18:13:30 +00:00
|
|
|
* >0 return value of the first signaled error >0 (in the case of no other errors)
|
2008-02-25 21:46:04 +00:00
|
|
|
* 0 everything OK
|
|
|
|
*/
|
2015-06-22 15:25:00 +00:00
|
|
|
int fsck_walk(struct object *obj, void *data, struct fsck_options *options);
|
fsck: require an actual buffer for non-blobs
The fsck_object() function takes in a buffer, but also a "struct
object". The rules for using these vary between types:
- for a commit, we'll use the provided buffer; if it's NULL, we'll
fall back to get_commit_buffer(), which loads from either an
in-memory cache or from disk. If the latter fails, we'd die(), which
is non-ideal for fsck.
- for a tag, a NULL buffer will fall back to loading the object from
disk (and failure would lead to an fsck error)
- for a tree, we _never_ look at the provided buffer, and always use
tree->buffer
- for a blob, we usually don't look at the buffer at all, unless it
has been marked as a .gitmodule file. In that case we check the
buffer given to us, or assume a NULL buffer is a very large blob
(and complain about it)
This is much more complex than it needs to be. It turns out that nobody
ever feeds a NULL buffer that isn't a blob:
- git-fsck calls fsck_object() only from fsck_obj(). That in turn is
called by one of:
- fsck_obj_buffer(), which is a callback to verify_pack(), which
unpacks everything except large blobs into a buffer (see
pack-check.c, lines 131-141).
- fsck_loose(), which hits a BUG() on non-blobs with a NULL buffer
(builtin/fsck.c, lines 639-640)
And in either case, we'll have just called parse_object_buffer()
anyway, which would segfault on a NULL buffer for commits or tags
(not for trees, but it would install a NULL tree->buffer which would
later cause a segfault)
- git-index-pack asserts that the buffer is non-NULL unless the object
is a blob (see builtin/index-pack.c, line 832)
- git-unpack-objects always writes a non-NULL buffer into its
obj_buffer hash, which is then fed to fsck_object(). (There is
actually a funny thing here where it does not store blob buffers at
all, nor does it call fsck on them; it does check any needed blobs
via fsck_finish() though).
Let's make the rules simpler, which reduces the amount of code and gives
us more flexibility in refactoring the fsck code. The new rules are:
- only blobs are allowed to pass a NULL buffer
- we always use the provided buffer, never pulling information from
the object struct
We don't have to adjust any callers, because they were already adhering
to these. Note that we do drop a few fsck identifiers for missing tags,
but that was all dead code (because nobody passed a NULL tag buffer).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-10-18 04:54:12 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Blob objects my pass a NULL data pointer, which indicates they are too large
|
|
|
|
* to fit in memory. All other types must pass a real buffer.
|
|
|
|
*/
|
2014-09-10 13:52:51 +00:00
|
|
|
int fsck_object(struct object *obj, void *data, unsigned long size,
|
2015-06-22 15:25:00 +00:00
|
|
|
struct fsck_options *options);
|
2008-02-25 21:46:04 +00:00
|
|
|
|
fsck: detect gitmodules files
In preparation for performing fsck checks on .gitmodules
files, this commit plumbs in the actual detection of the
files. Note that unlike most other fsck checks, this cannot
be a property of a single object: we must know that the
object is found at a ".gitmodules" path at the root tree of
a commit.
Since the fsck code only sees one object at a time, we have
to mark the related objects to fit the puzzle together. When
we see a commit we mark its tree as a root tree, and when
we see a root tree with a .gitmodules file, we mark the
corresponding blob to be checked.
In an ideal world, we'd check the objects in topological
order: commits followed by trees followed by blobs. In that
case we can avoid ever loading an object twice, since all
markings would be complete by the time we get to the marked
objects. And indeed, if we are checking a single packfile,
this is the order in which Git will generally write the
objects. But we can't count on that:
1. git-fsck may show us the objects in arbitrary order
(loose objects are fed in sha1 order, but we may also
have multiple packs, and we process each pack fully in
sequence).
2. The type ordering is just what git-pack-objects happens
to write now. The pack format does not require a
specific order, and it's possible that future versions
of Git (or a custom version trying to fool official
Git's fsck checks!) may order it differently.
3. We may not even be fscking all of the relevant objects
at once. Consider pushing with transfer.fsckObjects,
where one push adds a blob at path "foo", and then a
second push adds the same blob at path ".gitmodules".
The blob is not part of the second push at all, but we
need to mark and check it.
So in the general case, we need to make up to three passes
over the objects: once to make sure we've seen all commits,
then once to cover any trees we might have missed, and then
a final pass to cover any .gitmodules blobs we found in the
second pass.
We can simplify things a bit by loosening the requirement
that we find .gitmodules only at root trees. Technically
a file like "subdir/.gitmodules" is not parsed by Git, but
it's not unreasonable for us to declare that Git is aware of
all ".gitmodules" files and make them eligible for checking.
That lets us drop the root-tree requirement, which
eliminates one pass entirely. And it makes our worst case
much better: instead of potentially queueing every root tree
to be re-examined, the worst case is that we queue each
unique .gitmodules blob for a second look.
This patch just adds the boilerplate to find .gitmodules
files. The actual content checks will come in a subsequent
commit.
Signed-off-by: Jeff King <peff@peff.net>
2018-05-02 21:20:08 +00:00
|
|
|
/*
|
|
|
|
* Some fsck checks are context-dependent, and may end up queued; run this
|
|
|
|
* after completing all fsck_object() calls in order to resolve any remaining
|
|
|
|
* checks.
|
|
|
|
*/
|
|
|
|
int fsck_finish(struct fsck_options *options);
|
|
|
|
|
fsck: unify object-name code
Commit 90cf590f53 (fsck: optionally show more helpful info for broken
links, 2016-07-17) added a system for decorating objects with names. The
code is split across builtin/fsck.c (which gives the initial names) and
fsck.c (which adds to the names as it traverses the object graph). This
leads to some duplication, where both sites have near-identical
describe_object() functions (the difference being that the one in
builtin/fsck.c uses a circular array of buffers to allow multiple calls
in a single printf).
Let's provide a unified object_name API for fsck. That lets us drop the
duplication, as well as making the interface boundaries more clear
(which will let us refactor the implementation more in a future patch).
We'll leave describe_object() in builtin/fsck.c as a thin wrapper around
the new API, as it relies on a static global to make its many callers a
bit shorter.
We'll also convert the bare add_decoration() calls in builtin/fsck.c to
put_object_name(). This fixes two minor bugs:
1. We leak many small strings. add_decoration() has a last-one-wins
approach: it updates the decoration to the new string and returns
the old one. But we ignore the return value, leaking the old
string. This is quite common to trigger, since we look at reflogs:
the tip of any ref will be described both by looking at the actual
ref, as well as the latest reflog entry. So we'd always end up
leaking one of those strings.
2. The last-one-wins approach gives us lousy names. For instance, we
first look at all of the refs, and then all of the reflogs. So
rather than seeing "refs/heads/master", we're likely to overwrite
it with "HEAD@{12345678}". We're generally better off using the
first name we find.
And indeed, the test in t1450 expects this ugly HEAD@{} name. After
this patch, we've switched to using fsck_put_object_name()'s
first-one-wins semantics, and we output the more human-friendly
"refs/tags/julius" (and the test is updated accordingly).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-10-18 04:56:13 +00:00
|
|
|
/*
|
|
|
|
* Subsystem for storing human-readable names for each object.
|
|
|
|
*
|
|
|
|
* If fsck_enable_object_names() has not been called, all other functions are
|
|
|
|
* noops.
|
|
|
|
*
|
|
|
|
* Use fsck_put_object_name() to seed initial names (e.g. from refnames); the
|
|
|
|
* fsck code will extend that while walking trees, etc.
|
|
|
|
*
|
|
|
|
* Use fsck_get_object_name() to get a single name (or NULL if none). Or the
|
|
|
|
* more convenient describe_object(), which always produces an output string
|
|
|
|
* with the oid combined with the name (if any). Note that the return value
|
|
|
|
* points to a rotating array of static buffers, and may be invalidated by a
|
|
|
|
* subsequent call.
|
|
|
|
*/
|
|
|
|
void fsck_enable_object_names(struct fsck_options *options);
|
|
|
|
const char *fsck_get_object_name(struct fsck_options *options,
|
2019-10-18 04:57:37 +00:00
|
|
|
const struct object_id *oid);
|
fsck: unify object-name code
Commit 90cf590f53 (fsck: optionally show more helpful info for broken
links, 2016-07-17) added a system for decorating objects with names. The
code is split across builtin/fsck.c (which gives the initial names) and
fsck.c (which adds to the names as it traverses the object graph). This
leads to some duplication, where both sites have near-identical
describe_object() functions (the difference being that the one in
builtin/fsck.c uses a circular array of buffers to allow multiple calls
in a single printf).
Let's provide a unified object_name API for fsck. That lets us drop the
duplication, as well as making the interface boundaries more clear
(which will let us refactor the implementation more in a future patch).
We'll leave describe_object() in builtin/fsck.c as a thin wrapper around
the new API, as it relies on a static global to make its many callers a
bit shorter.
We'll also convert the bare add_decoration() calls in builtin/fsck.c to
put_object_name(). This fixes two minor bugs:
1. We leak many small strings. add_decoration() has a last-one-wins
approach: it updates the decoration to the new string and returns
the old one. But we ignore the return value, leaking the old
string. This is quite common to trigger, since we look at reflogs:
the tip of any ref will be described both by looking at the actual
ref, as well as the latest reflog entry. So we'd always end up
leaking one of those strings.
2. The last-one-wins approach gives us lousy names. For instance, we
first look at all of the refs, and then all of the reflogs. So
rather than seeing "refs/heads/master", we're likely to overwrite
it with "HEAD@{12345678}". We're generally better off using the
first name we find.
And indeed, the test in t1450 expects this ugly HEAD@{} name. After
this patch, we've switched to using fsck_put_object_name()'s
first-one-wins semantics, and we output the more human-friendly
"refs/tags/julius" (and the test is updated accordingly).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-10-18 04:56:13 +00:00
|
|
|
__attribute__((format (printf,3,4)))
|
2019-10-18 04:57:37 +00:00
|
|
|
void fsck_put_object_name(struct fsck_options *options,
|
|
|
|
const struct object_id *oid,
|
fsck: unify object-name code
Commit 90cf590f53 (fsck: optionally show more helpful info for broken
links, 2016-07-17) added a system for decorating objects with names. The
code is split across builtin/fsck.c (which gives the initial names) and
fsck.c (which adds to the names as it traverses the object graph). This
leads to some duplication, where both sites have near-identical
describe_object() functions (the difference being that the one in
builtin/fsck.c uses a circular array of buffers to allow multiple calls
in a single printf).
Let's provide a unified object_name API for fsck. That lets us drop the
duplication, as well as making the interface boundaries more clear
(which will let us refactor the implementation more in a future patch).
We'll leave describe_object() in builtin/fsck.c as a thin wrapper around
the new API, as it relies on a static global to make its many callers a
bit shorter.
We'll also convert the bare add_decoration() calls in builtin/fsck.c to
put_object_name(). This fixes two minor bugs:
1. We leak many small strings. add_decoration() has a last-one-wins
approach: it updates the decoration to the new string and returns
the old one. But we ignore the return value, leaking the old
string. This is quite common to trigger, since we look at reflogs:
the tip of any ref will be described both by looking at the actual
ref, as well as the latest reflog entry. So we'd always end up
leaking one of those strings.
2. The last-one-wins approach gives us lousy names. For instance, we
first look at all of the refs, and then all of the reflogs. So
rather than seeing "refs/heads/master", we're likely to overwrite
it with "HEAD@{12345678}". We're generally better off using the
first name we find.
And indeed, the test in t1450 expects this ugly HEAD@{} name. After
this patch, we've switched to using fsck_put_object_name()'s
first-one-wins semantics, and we output the more human-friendly
"refs/tags/julius" (and the test is updated accordingly).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-10-18 04:56:13 +00:00
|
|
|
const char *fmt, ...);
|
|
|
|
const char *fsck_describe_object(struct fsck_options *options,
|
2019-10-18 04:57:37 +00:00
|
|
|
const struct object_id *oid);
|
fsck: unify object-name code
Commit 90cf590f53 (fsck: optionally show more helpful info for broken
links, 2016-07-17) added a system for decorating objects with names. The
code is split across builtin/fsck.c (which gives the initial names) and
fsck.c (which adds to the names as it traverses the object graph). This
leads to some duplication, where both sites have near-identical
describe_object() functions (the difference being that the one in
builtin/fsck.c uses a circular array of buffers to allow multiple calls
in a single printf).
Let's provide a unified object_name API for fsck. That lets us drop the
duplication, as well as making the interface boundaries more clear
(which will let us refactor the implementation more in a future patch).
We'll leave describe_object() in builtin/fsck.c as a thin wrapper around
the new API, as it relies on a static global to make its many callers a
bit shorter.
We'll also convert the bare add_decoration() calls in builtin/fsck.c to
put_object_name(). This fixes two minor bugs:
1. We leak many small strings. add_decoration() has a last-one-wins
approach: it updates the decoration to the new string and returns
the old one. But we ignore the return value, leaking the old
string. This is quite common to trigger, since we look at reflogs:
the tip of any ref will be described both by looking at the actual
ref, as well as the latest reflog entry. So we'd always end up
leaking one of those strings.
2. The last-one-wins approach gives us lousy names. For instance, we
first look at all of the refs, and then all of the reflogs. So
rather than seeing "refs/heads/master", we're likely to overwrite
it with "HEAD@{12345678}". We're generally better off using the
first name we find.
And indeed, the test in t1450 expects this ugly HEAD@{} name. After
this patch, we've switched to using fsck_put_object_name()'s
first-one-wins semantics, and we output the more human-friendly
"refs/tags/julius" (and the test is updated accordingly).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-10-18 04:56:13 +00:00
|
|
|
|
2008-02-25 21:46:04 +00:00
|
|
|
#endif
|