Subject: Re: [PATCH v5 01/12] wt-status: provide function to expose status for trees

From: Junio C Hamano <[email-masked]>
Date: Tue, 21 Oct 2025 13:38:05 -0700

Patrick Steinhardt <[email-masked]> writes:

> diff --git a/wt-status.c b/wt-status.c
> index 8ffe6d3988f..b66edbfca6c 100644
> --- a/wt-status.c
> +++ b/wt-status.c
> @@ -612,6 +612,30 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
>  	}
>  }
>  
> +void wt_status_collect_changes_trees(struct wt_status *s,
> +				     const struct object_id *old_treeish,
> +				     const struct object_id *new_treeish)
> +{
> +	struct diff_options opts = { 0 };
> +
> +	repo_diff_setup(s->repo, &opts);
> +	opts.output_format = DIFF_FORMAT_CALLBACK;
> +	opts.format_callback = wt_status_collect_updated_cb;
> +	opts.format_callback_data = s;
> +	opts.detect_rename = s->detect_rename >= 0 ? s->detect_rename : opts.detect_rename;
> +	opts.rename_limit = s->rename_limit >= 0 ? s->rename_limit : opts.rename_limit;
> +	opts.rename_score = s->rename_score >= 0 ? s->rename_score : opts.rename_score;
> +	opts.flags.recursive = 1;
> +	diff_setup_done(&opts);

This is obviously modelled after collect_changes_index(), whose
callback this function reuses, except that the set up to prepare for
running a diff is different from their way to compare between HEAD
(or void, if root) with the index.  We also do not have to worry
about sparse checkout.  We do not have to worry about
ignore-submodule argument, either.

> +	diff_tree_oid(old_treeish, new_treeish, "", &opts);
> +	diffcore_std(&opts);
> +	diff_flush(&opts);
> +	wt_status_get_state(s->repo, &s->state, 0);
> +
> +	diff_free(&opts);
> +}
> +
>  static void wt_status_collect_changes_worktree(struct wt_status *s)
>  {
>  	struct rev_info rev;
> diff --git a/wt-status.h b/wt-status.h
> index e40a27214a7..924d7a5fa99 100644
> --- a/wt-status.h
> +++ b/wt-status.h
> @@ -153,6 +153,9 @@ void wt_status_add_cut_line(struct wt_status *s);
> ...

Let's add a comment to help callers of this function that the
changes going from "old" to "new" are recorded as if they are
"staged" changes and recorded on the "index" side.  It can only be
inferred from the use of collect_updated_cb, which was written to be
used by wt_status_collect_changes_index(), and probably it is a bit
brutal to expect for casual readers to realize on their own.

> +void wt_status_collect_changes_trees(struct wt_status *s,
> +				     const struct object_id *old_treeish,
> +				     const struct object_id *new_treeish);