From: mkoegler@auto.tuwien.ac.at (Martin Koegler)
To: "Shawn O. Pearce" <spearce@spearce.org>
Cc: Nicolas Pitre <nico@cam.org>, Junio C Hamano <gitster@pobox.com>,
git@vger.kernel.org
Subject: Re: [RFC PATCH] Remove object-refs from fsck
Date: Thu, 14 Feb 2008 20:07:47 +0100 [thread overview]
Message-ID: <20080214190746.GC26527@auto.tuwien.ac.at> (raw)
In-Reply-To: <20080214090013.GK24004@spearce.org>
On Thu, Feb 14, 2008 at 04:00:13AM -0500, Shawn O. Pearce wrote:
>
> +static int object_exists(const unsigned char *sha1)
> +{
> + struct object *obj = lookup_object(sha1);
> + if (obj && obj->flags & FSCKED)
> + return 1;
> + return has_sha1_file(sha1);
> +}
> +
> +static void broken_link(struct object *obj,
> + enum object_type ref_type,
> + const unsigned char *ref_sha1)
> +{
> + printf("broken link from %7s %s\n",
> + typename(obj->type), sha1_to_hex(obj->sha1));
> + printf(" to %7s %s\n",
> + typename(ref_type), sha1_to_hex(ref_sha1));
> + errors_found |= ERROR_REACHABLE;
> +}
> +
> +static void broken_tree(struct tree *item)
> +{
> + struct tree_desc desc;
> +
> + item->object.parsed = 0;
> + if (parse_tree(item) < 0)
> + return; /* error already displayed */
> +
> + init_tree_desc(&desc, item->buffer, item->size);
> + while (desc.size) {
> + unsigned mode;
> + const char *name;
> + const unsigned char *sha1;
> +
> + sha1 = tree_entry_extract(&desc, &name, &mode);
> + update_tree_entry(&desc);
> + if (S_ISGITLINK(mode) || object_exists(sha1))
> + continue;
> + if (S_ISDIR(mode))
> + broken_link(&item->object, OBJ_TREE, sha1);
> + else
> + broken_link(&item->object, OBJ_BLOB, sha1);
> + }
> + free(item->buffer);
> + item->buffer = NULL;
> +}
> +
> +static void broken_commit(struct commit *commit)
> +{
> + struct tree *tree = commit->tree;
> + struct commit_list *pp;
> +
> + if (tree && !object_exists(tree->object.sha1))
> + broken_link(&commit->object, OBJ_TREE, tree->object.sha1);
> +
> + pp = commit->parents;
> + while (pp) {
> + struct commit *p = pp->item;
> + if (p && !object_exists(p->object.sha1))
> + broken_link(&commit->object, OBJ_COMMIT, p->object.sha1);
> + pp = pp->next;
> + }
> +}
> +
> +static void broken_tag(struct tag *tag)
> +{
> + struct object *ref = tag->tagged;
> + if (ref && !object_exists(ref->sha1))
> + broken_link(&tag->object, ref->type, ref->sha1);
> +}
> +
> /*
> * Check a single reachable object
> */
> static void check_reachable_object(struct object *obj)
> {
> - const struct object_refs *refs;
> -
> /*
> * We obviously want the object to be parsed,
> * except if it was in a pack-file and we didn't
> @@ -84,21 +155,28 @@ static void check_reachable_object(struct object *obj)
> }
>
> /*
> - * Check that everything that we try to reference is also good.
> + * If the fsck routines found this object WANTING
> + * then we need to re-evaluate what it wanted and
> + * report on those broken links.
> */
> - refs = lookup_object_refs(obj);
> - if (refs) {
> - unsigned j;
> - for (j = 0; j < refs->count; j++) {
> - struct object *ref = refs->ref[j];
> - if (ref->parsed ||
> - (has_sha1_file(ref->sha1)))
> - continue;
> - printf("broken link from %7s %s\n",
> - typename(obj->type), sha1_to_hex(obj->sha1));
> - printf(" to %7s %s\n",
> - typename(ref->type), sha1_to_hex(ref->sha1));
> - errors_found |= ERROR_REACHABLE;
> + if (obj->flags & WANTING) {
> + switch (obj->type) {
> + case OBJ_TREE:
> + broken_tree((struct tree *) obj);
> + break;
> +
> + case OBJ_COMMIT:
> + broken_commit((struct commit *) obj);
> + break;
> +
> + case OBJ_TAG:
> + broken_tag((struct tag *) obj);
> + break;
> +
> + default:
> + objerror(obj,
> + "type '%d' has broken link (internal fsck error)",
> + obj->type);
> }
> }
> }
> @@ -181,7 +259,7 @@ static void check_object(struct object *obj)
> if (verbose)
> fprintf(stderr, "Checking %s\n", sha1_to_hex(obj->sha1));
>
> - if (obj->flags & REACHABLE)
> + if (obj->flags & SEEN)
> check_reachable_object(obj);
> else
> check_unreachable_object(obj);
> @@ -309,6 +387,15 @@ static int fsck_tree(struct tree *item)
> has_bad_modes = 1;
> }
>
> + /*
> + * If the SHA-1 should exist in this repository but
> + * we are missing it flag this tree as WANTING. We
> + * will revisit this error later once we determine
> + * this tree is SEEN.
> + */
> + if (!S_ISGITLINK(mode) && !object_exists(sha1))
> + item->object.flags |= WANTING;
> +
> if (o_name) {
> switch (verify_ordered(o_mode, o_name, mode, name)) {
> case TREE_UNORDERED:
> @@ -367,10 +454,15 @@ static int fsck_commit(struct commit *commit)
> return objerror(&commit->object, "invalid format - expected 'tree' line");
> if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
> return objerror(&commit->object, "invalid 'tree' line format - bad sha1");
> + if (!object_exists(tree_sha1))
> + commit->object.flags |= WANTING;
> +
How do we verify, that tree_sha1 is a tree?
> buffer += 46;
> while (!memcmp(buffer, "parent ", 7)) {
> if (get_sha1_hex(buffer+7, sha1) || buffer[47] != '\n')
> return objerror(&commit->object, "invalid 'parent' line format - bad sha1");
> + if (!object_exists(sha1))
> + commit->object.flags |= WANTING;
How do we verify, that sha1 is a commit?
> buffer += 48;
> }
> if (memcmp(buffer, "author ", 7))
> @@ -395,6 +487,9 @@ static int fsck_tag(struct tag *tag)
> if (!tagged) {
> return objerror(&tag->object, "could not load tagged object");
> }
> + if (!object_exists(tagged->sha1))
> + tag->object.flags |= WANTING;
> +
Same here. Where do we check the type?
mfg Martin Kögler
next prev parent reply other threads:[~2008-02-14 19:08 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-10 17:58 [RFC Patch] Preventing corrupt objects from entering the repository Martin Koegler
2008-02-11 0:00 ` Junio C Hamano
2008-02-11 0:33 ` Nicolas Pitre
2008-02-11 19:56 ` Martin Koegler
2008-02-11 20:41 ` Nicolas Pitre
2008-02-11 21:58 ` Martin Koegler
2008-02-12 16:02 ` Nicolas Pitre
2008-02-12 19:04 ` Martin Koegler
2008-02-12 20:22 ` Nicolas Pitre
2008-02-12 21:38 ` Martin Koegler
2008-02-12 21:51 ` Nicolas Pitre
2008-02-13 6:20 ` Shawn O. Pearce
2008-02-13 7:39 ` Martin Koegler
2008-02-14 9:00 ` [RFC PATCH] Remove object-refs from fsck Shawn O. Pearce
2008-02-14 19:07 ` Martin Koegler [this message]
2008-02-13 7:42 ` [RFC Patch] Preventing corrupt objects from entering the repository Shawn O. Pearce
2008-02-13 8:11 ` Martin Koegler
2008-02-13 12:01 ` Johannes Schindelin
2008-02-14 6:16 ` Shawn O. Pearce
2008-02-14 19:04 ` Martin Koegler
2008-02-15 0:06 ` Johannes Schindelin
2008-02-15 7:18 ` Martin Koegler
2008-02-12 7:20 ` Martin Koegler
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=20080214190746.GC26527@auto.tuwien.ac.at \
--to=mkoegler@auto.tuwien.ac.at \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=nico@cam.org \
--cc=spearce@spearce.org \
/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;
as well as URLs for NNTP newsgroup(s).