git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
MKMartin Koegler <mkoegler@auto.tuwien.ac.at>
Date
Feb 14, 2008, 19:07 UTC
Message-ID
<20080214190746.GC26527@auto.tuwien.ac.at>
In-Reply-To
<20080214090013.GK24004@spearce.org>
On Thu, Feb 14, 2008 at 04:00:13AM -0500, Shawn O. Pearce wrote:
Show 156 quoted lines
>  
> +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?
Show 6 quoted lines
>  	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?
Show 10 quoted lines
>  		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
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 15 of 23 in “Preventing corrupt objects from entering the repository”
  1. Preventing corrupt objects from entering the repositoryMartin Koegler, Feb 10, 2008
  2. Junio C HamanoFeb 11, 2008
  3. Nicolas PitreFeb 11, 2008
  4. Martin KoeglerFeb 11, 2008
  5. Nicolas PitreFeb 11, 2008
  6. Martin KoeglerFeb 11, 2008
  7. Nicolas PitreFeb 12, 2008
  8. Martin KoeglerFeb 12, 2008
  9. Nicolas PitreFeb 12, 2008
  10. Martin KoeglerFeb 12, 2008
  11. Nicolas PitreFeb 12, 2008
  12. Shawn O. PearceFeb 13, 2008
  13. Martin KoeglerFeb 13, 2008
  14. Remove object-refs from fsckShawn O. Pearce, Feb 14, 2008
  15. Martin KoeglerFeb 14, 2008
  16. Shawn O. PearceFeb 13, 2008
  17. Martin KoeglerFeb 13, 2008
  18. Johannes SchindelinFeb 13, 2008
  19. Shawn O. PearceFeb 14, 2008
  20. Martin KoeglerFeb 14, 2008
  21. Johannes SchindelinFeb 15, 2008
  22. Martin KoeglerFeb 15, 2008
  23. Martin KoeglerFeb 12, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.