]> git.ipfire.org Git - thirdparty/git.git/commitdiff
revision: optionally record matches with pathspec elements
authorJunio C Hamano <gitster@pobox.com>
Wed, 3 Apr 2024 18:14:48 +0000 (23:44 +0530)
committerJunio C Hamano <gitster@pobox.com>
Wed, 3 Apr 2024 21:55:21 +0000 (14:55 -0700)
Unlike "git add" and other end-user facing commands, 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 do 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@pobox.com>
builtin/add.c
builtin/checkout.c
builtin/commit.c
diff-lib.c
read-cache-ll.h
read-cache.c
revision.h

index 393c10cbcf6315efb525b38db26e218bf6b1959d..dc4b42d0ad3d16020db3ed93cbe99d04426882af 100644 (file)
@@ -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);
index 2e8b0d18f445b1307e264634f69c8ce0a3a5c68a..56d18288563849f28cd31a8ee92d787ed80ad595 100644 (file)
@@ -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);
index b27b56c8bef3ea0c968392095519017151709ca2..8f31decc6b2ea0511784b786391b08faae2c4c91 100644 (file)
@@ -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))
index 1cd790a4d2bef6a3df8a6eb080622ccaa6749fa3..683f11e50953a659dcdb075ce84eb92a19064077 100644 (file)
@@ -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 &&
index 2a50a784f0ec6ae4da94fed41345e625c5bbce1c..09414afd0472ed79a4a7f082278328c1446f5e8a 100644 (file)
@@ -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);
index f546cf7875cbfefddbec2449e8303786e485a8dd..e1723ad796f198823f4bf5ac3712881d80866b63 100644 (file)
@@ -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;
index 94c43138bc3e68651accecf79cdf4c28ba98582f..0e470d1df19f690586378a006d9c9145fb7386c7 100644 (file)
@@ -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;
 
        /*