Re: [PATCH v2 1/3] read-cache: optionally collect pathspec matching info

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

 



On Fri, 29 Mar 2024, Junio C Hamano <gitster@xxxxxxxxx> wrote:
> Junio C Hamano <gitster@xxxxxxxxx> writes:
> 
> > A new parameter to run_diff_files() came as a bit of surprise to me.
> >
> > When I responded to the previous round, I somehow thought that we'd
> > add a new member to the rev structure that points at an optional
> > .ps_matched member next to the existing .prune_data member.  
> >
> > That way, it would hopefully be easy for a future code to see if a
> > "diff" invocation, not necessarily run_diff_files() that compares
> > the working tree and the index, consumed all the pathspec elements.
> > If such a new .ps_matched member is initialized to NULL, all the
> > patch noise we see in this patch will become unnecessary, no?
> 
> This is how such a change may look like.  After applying [2/3] and
> [3/3] steps from your series on top of this patch, the updated tests
> in your series (2200 and 7501) seem to still pass.

This seems perfect. I hope you're OK with me using this patch as a base
for patch [2/3] and [3/3]. :)

> ------- >8 ------------- >8 ------------- >8 ------------- >8 -------
> 
> Subject: [PATCH] revision: optionally record matches with pathspec elements
> 
> Unlike "git add" and other end-user facing command, where it is
> diagnosed as an error to give a pathspec with an element that does
> not match any path, the diff machinery does not care if some
> elements of the pathspec does not match.  Given that the diff
> machinery is heavily used in pathspec-limited "git log" machinery,
> and it is common for a path to come and go while traversing the
> project history, this is usually a good thing.
> 
> However, in some cases we would want to know if all the pathspec
> elements matched.  For example, "git add -u <pathspec>" internally
> uses the machinery used by "git diff-files" to decide contents from
> what paths to add to the index, and as an end-user facing command,
> "git add -u" would want to report an unmatched pathspec element.
> 
> Add a new .ps_matched member next to the .prune_data member in
> "struct rev_info" so that we can optionally keep track of the use of
> .prune_data pathspec elements that can be inspected by the caller.
> 
> Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
> ---
>  builtin/add.c      |  4 ++--
>  builtin/checkout.c |  3 ++-
>  builtin/commit.c   |  2 +-
>  diff-lib.c         | 11 ++++++++++-
>  read-cache-ll.h    |  4 ++--
>  read-cache.c       |  8 +++++---
>  revision.h         |  1 +
>  7 files changed, 23 insertions(+), 10 deletions(-)
> 
> diff --git a/builtin/add.c b/builtin/add.c
> index 393c10cbcf..dc4b42d0ad 100644
> --- a/builtin/add.c
> +++ b/builtin/add.c
> @@ -553,8 +553,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
>  		exit_status |= renormalize_tracked_files(&pathspec, flags);
>  	else
>  		exit_status |= add_files_to_cache(the_repository, prefix,
> -						  &pathspec, include_sparse,
> -						  flags);
> +						  &pathspec, NULL,
> +						  include_sparse, flags);
>  
>  	if (add_new_files)
>  		exit_status |= add_files(&dir, flags);
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index 2e8b0d18f4..56d1828856 100644
> --- a/builtin/checkout.c
> +++ b/builtin/checkout.c
> @@ -878,7 +878,8 @@ static int merge_working_tree(const struct checkout_opts *opts,
>  			 * entries in the index.
>  			 */
>  
> -			add_files_to_cache(the_repository, NULL, NULL, 0, 0);
> +			add_files_to_cache(the_repository, NULL, NULL, NULL, 0,
> +					   0);
>  			init_merge_options(&o, the_repository);
>  			o.verbosity = 0;
>  			work = write_in_core_index_as_tree(the_repository);
> diff --git a/builtin/commit.c b/builtin/commit.c
> index b27b56c8be..8f31decc6b 100644
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -444,7 +444,7 @@ static const char *prepare_index(const char **argv, const char *prefix,
>  		repo_hold_locked_index(the_repository, &index_lock,
>  				       LOCK_DIE_ON_ERROR);
>  		add_files_to_cache(the_repository, also ? prefix : NULL,
> -				   &pathspec, 0, 0);
> +				   &pathspec, NULL, 0, 0);
>  		refresh_cache_or_die(refresh_flags);
>  		cache_tree_update(&the_index, WRITE_TREE_SILENT);
>  		if (write_locked_index(&the_index, &index_lock, 0))
> diff --git a/diff-lib.c b/diff-lib.c
> index 1cd790a4d2..683f11e509 100644
> --- a/diff-lib.c
> +++ b/diff-lib.c
> @@ -127,7 +127,16 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
>  		if (diff_can_quit_early(&revs->diffopt))
>  			break;
>  
> -		if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
> +		/*
> +		 * NEEDSWORK:
> +		 * Here we filter with pathspec but the result is further
> +		 * filtered out when --relative is in effect.  To end-users,
> +		 * a pathspec element that matched only to paths outside the
> +		 * current directory is like not matching anything at all;
> +		 * the handling of ps_matched[] here may become problematic
> +		 * if/when we add the "--error-unmatch" option to "git diff".
> +		 */
> +		if (!ce_path_match(istate, ce, &revs->prune_data, revs->ps_matched))
>  			continue;
>  
>  		if (revs->diffopt.prefix &&
> diff --git a/read-cache-ll.h b/read-cache-ll.h
> index 2a50a784f0..09414afd04 100644
> --- a/read-cache-ll.h
> +++ b/read-cache-ll.h
> @@ -480,8 +480,8 @@ extern int verify_ce_order;
>  int cmp_cache_name_compare(const void *a_, const void *b_);
>  
>  int add_files_to_cache(struct repository *repo, const char *prefix,
> -		       const struct pathspec *pathspec, int include_sparse,
> -		       int flags);
> +		       const struct pathspec *pathspec, char *ps_matched,
> +		       int include_sparse, int flags);
>  
>  void overlay_tree_on_index(struct index_state *istate,
>  			   const char *tree_name, const char *prefix);
> diff --git a/read-cache.c b/read-cache.c
> index f546cf7875..e1723ad796 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -3958,8 +3958,8 @@ static void update_callback(struct diff_queue_struct *q,
>  }
>  
>  int add_files_to_cache(struct repository *repo, const char *prefix,
> -		       const struct pathspec *pathspec, int include_sparse,
> -		       int flags)
> +		       const struct pathspec *pathspec, char *ps_matched,
> +		       int include_sparse, int flags)
>  {
>  	struct update_callback_data data;
>  	struct rev_info rev;
> @@ -3971,8 +3971,10 @@ int add_files_to_cache(struct repository *repo, const char *prefix,
>  
>  	repo_init_revisions(repo, &rev, prefix);
>  	setup_revisions(0, NULL, &rev, NULL);
> -	if (pathspec)
> +	if (pathspec) {
>  		copy_pathspec(&rev.prune_data, pathspec);
> +		rev.ps_matched = ps_matched;
> +	}
>  	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
>  	rev.diffopt.format_callback = update_callback;
>  	rev.diffopt.format_callback_data = &data;
> diff --git a/revision.h b/revision.h
> index 94c43138bc..0e470d1df1 100644
> --- a/revision.h
> +++ b/revision.h
> @@ -142,6 +142,7 @@ struct rev_info {
>  	/* Basic information */
>  	const char *prefix;
>  	const char *def;
> +	char *ps_matched; /* optionally record matches of prune_data */
>  	struct pathspec prune_data;
>  
>  	/*
> -- 
> 2.44.0-413-gd6fd04375f
> 




[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