Subject: Re: [RFC PATCH 3/4] fsck: support referenced lazy objects

From: Junio C Hamano <[email-masked]>
Date: Thu, 27 Jul 2017 12:17:37 -0700

Jonathan Tan <[email-masked]> writes:

> Teach fsck to not treat missing objects indirectly pointed to by refs as
> an error when extensions.lazyobject is set.
>
> Signed-off-by: Jonathan Tan <[email-masked]>
> ---
>  builtin/fsck.c         | 11 +++++++++++
>  t/t0410-lazy-object.sh | 27 +++++++++++++++++++++++++++
>  2 files changed, 38 insertions(+)
>
> diff --git a/builtin/fsck.c b/builtin/fsck.c
> index e29ff760b..238532cc2 100644
> --- a/builtin/fsck.c
> +++ b/builtin/fsck.c
> @@ -149,6 +149,15 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
>  		return 0;
>  	obj->flags |= REACHABLE;
>  	if (!(obj->flags & HAS_OBJ)) {
> +		if (repository_format_lazy_object)
> +			/*
> +			 * Return immediately; this is not an error, and further
> +			 * recursion does not need to be performed on this
> +			 * object since it is missing (so it does not need to be
> +			 * added to "pending").
> +			 */
> +			return 0;
> +

The same comment as 2/4 applies here.

> @@ -212,6 +221,8 @@ static void check_reachable_object(struct object *obj)
>  	 * do a full fsck
>  	 */
>  	if (!(obj->flags & HAS_OBJ)) {
> +		if (repository_format_lazy_object)
> +			return;
>  		if (has_sha1_pack(obj->oid.hash))
>  			return; /* it is in pack - forget about it */
>  		printf("missing %s %s\n", printable_type(obj),

Also this reminds as a related issue.  Imagine:

 - An object X was once retrieved, perhaps but not necessarily
   lazily, together with another object Y that is referred to by X
   (e.g. X is a tree, Y is a blob in the directory at path D, which
   is represented by X).

 - The same blob Y is added to the index in a different directory at
   path E.

 - The user decides to make this a slimmed-down "narrow clone" style
   repository and tells Git that path D is not interesting.  We lose
   X, but not Y because Y is still referenced from the index.

 - "git reset --hard" happens, and there no longer is any reference
   to Y.

Now, when we run fsck, should we diagnose Y as "unreachable and/or
dangling"?