Re: [RFC PATCH] Remove object-refs from fsck

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux