Skip to content

Commit d75ec4c

Browse files
committed
Merge branch 'gt/add-u-commit-i-pathspec-check'
"git add -u <pathspec>" and "git commit [-i] <pathspec>" did not diagnose a pathspec element that did not match any files in certain situations, unlike "git add <pathspec>" did. * gt/add-u-commit-i-pathspec-check: builtin/add: error out when passing untracked path with -u builtin/commit: error out when passing untracked path with -i revision: optionally record matches with pathspec elements
2 parents 6c142bc + 7de13cf commit d75ec4c

File tree

9 files changed

+46
-25
lines changed

9 files changed

+46
-25
lines changed

builtin/add.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
368368
int add_new_files;
369369
int require_pathspec;
370370
char *seen = NULL;
371+
char *ps_matched = NULL;
371372
struct lock_file lock_file = LOCK_INIT;
372373

373374
git_config(add_config, NULL);
@@ -545,12 +546,17 @@ int cmd_add(int argc, const char **argv, const char *prefix)
545546

546547
begin_odb_transaction();
547548

549+
ps_matched = xcalloc(pathspec.nr, 1);
548550
if (add_renormalize)
549551
exit_status |= renormalize_tracked_files(&pathspec, flags);
550552
else
551553
exit_status |= add_files_to_cache(the_repository, prefix,
552-
&pathspec, include_sparse,
553-
flags);
554+
&pathspec, ps_matched,
555+
include_sparse, flags);
556+
557+
if (take_worktree_changes && !add_renormalize && !ignore_add_errors &&
558+
report_path_error(ps_matched, &pathspec))
559+
exit(128);
554560

555561
if (add_new_files)
556562
exit_status |= add_files(&dir, flags);
@@ -564,6 +570,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
564570
COMMIT_LOCK | SKIP_IF_UNCHANGED))
565571
die(_("unable to write new index file"));
566572

573+
free(ps_matched);
567574
dir_clear(&dir);
568575
clear_pathspec(&pathspec);
569576
return exit_status;

builtin/checkout.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,8 @@ static int merge_working_tree(const struct checkout_opts *opts,
882882
* entries in the index.
883883
*/
884884

885-
add_files_to_cache(the_repository, NULL, NULL, 0, 0);
885+
add_files_to_cache(the_repository, NULL, NULL, NULL, 0,
886+
0);
886887
init_merge_options(&o, the_repository);
887888
o.verbosity = 0;
888889
work = write_in_core_index_as_tree(the_repository);

builtin/commit.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,16 +441,21 @@ static const char *prepare_index(const char **argv, const char *prefix,
441441
* (B) on failure, rollback the real index.
442442
*/
443443
if (all || (also && pathspec.nr)) {
444+
char *ps_matched = xcalloc(pathspec.nr, 1);
444445
repo_hold_locked_index(the_repository, &index_lock,
445446
LOCK_DIE_ON_ERROR);
446447
add_files_to_cache(the_repository, also ? prefix : NULL,
447-
&pathspec, 0, 0);
448+
&pathspec, ps_matched, 0, 0);
449+
if (!all && report_path_error(ps_matched, &pathspec))
450+
exit(128);
451+
448452
refresh_cache_or_die(refresh_flags);
449453
cache_tree_update(&the_index, WRITE_TREE_SILENT);
450454
if (write_locked_index(&the_index, &index_lock, 0))
451455
die(_("unable to write new index file"));
452456
commit_style = COMMIT_NORMAL;
453457
ret = get_lock_file_path(&index_lock);
458+
free(ps_matched);
454459
goto out;
455460
}
456461

diff-lib.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,16 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
127127
if (diff_can_quit_early(&revs->diffopt))
128128
break;
129129

130-
if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
130+
/*
131+
* NEEDSWORK:
132+
* Here we filter with pathspec but the result is further
133+
* filtered out when --relative is in effect. To end-users,
134+
* a pathspec element that matched only to paths outside the
135+
* current directory is like not matching anything at all;
136+
* the handling of ps_matched[] here may become problematic
137+
* if/when we add the "--error-unmatch" option to "git diff".
138+
*/
139+
if (!ce_path_match(istate, ce, &revs->prune_data, revs->ps_matched))
131140
continue;
132141

133142
if (revs->diffopt.prefix &&

read-cache-ll.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,8 @@ extern int verify_ce_order;
480480
int cmp_cache_name_compare(const void *a_, const void *b_);
481481

482482
int add_files_to_cache(struct repository *repo, const char *prefix,
483-
const struct pathspec *pathspec, int include_sparse,
484-
int flags);
483+
const struct pathspec *pathspec, char *ps_matched,
484+
int include_sparse, int flags);
485485

486486
void overlay_tree_on_index(struct index_state *istate,
487487
const char *tree_name, const char *prefix);

read-cache.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3958,8 +3958,8 @@ static void update_callback(struct diff_queue_struct *q,
39583958
}
39593959

39603960
int add_files_to_cache(struct repository *repo, const char *prefix,
3961-
const struct pathspec *pathspec, int include_sparse,
3962-
int flags)
3961+
const struct pathspec *pathspec, char *ps_matched,
3962+
int include_sparse, int flags)
39633963
{
39643964
struct update_callback_data data;
39653965
struct rev_info rev;
@@ -3971,8 +3971,10 @@ int add_files_to_cache(struct repository *repo, const char *prefix,
39713971

39723972
repo_init_revisions(repo, &rev, prefix);
39733973
setup_revisions(0, NULL, &rev, NULL);
3974-
if (pathspec)
3974+
if (pathspec) {
39753975
copy_pathspec(&rev.prune_data, pathspec);
3976+
rev.ps_matched = ps_matched;
3977+
}
39763978
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
39773979
rev.diffopt.format_callback = update_callback;
39783980
rev.diffopt.format_callback_data = &data;

revision.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ struct rev_info {
142142
/* Basic information */
143143
const char *prefix;
144144
const char *def;
145+
char *ps_matched; /* optionally record matches of prune_data */
145146
struct pathspec prune_data;
146147

147148
/*

t/t2200-add-update.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ test_expect_success 'update did not touch untracked files' '
6565
test_must_be_empty out
6666
'
6767

68+
test_expect_success 'error out when passing untracked path' '
69+
git reset --hard &&
70+
echo content >>baz &&
71+
echo content >>top &&
72+
test_must_fail git add -u baz top 2>err &&
73+
test_grep -e "error: pathspec .baz. did not match any file(s) known to git" err &&
74+
git diff --cached --name-only >actual &&
75+
test_must_be_empty actual
76+
'
77+
6878
test_expect_success 'cache tree has not been corrupted' '
6979
7080
git ls-files -s |

t/t7501-commit-basic-functionality.sh

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,22 +101,8 @@ test_expect_success 'fail to commit untracked file (even with --include/--only)'
101101
test_must_fail git commit --only -m "baz" baz 2>err &&
102102
test_grep -e "$error" err &&
103103
104-
# TODO: as for --include, the below command will fail because
105-
# nothing is staged. If something was staged, it would not fail
106-
# even though the provided pathspec does not match any tracked
107-
# path. (However, the untracked paths that match the pathspec are
108-
# not committed and only the staged changes get committed.)
109-
# In either cases, no error is returned to stderr like in (--only
110-
# and without --only/--include) cases. In a similar manner,
111-
# "git add -u baz" also does not error out.
112-
#
113-
# Therefore, the below test is just to document the current behavior
114-
# and is not an endorsement to the current behavior, and we may
115-
# want to fix this. And when that happens, this test should be
116-
# updated accordingly.
117-
118104
test_must_fail git commit --include -m "baz" baz 2>err &&
119-
test_must_be_empty err
105+
test_grep -e "$error" err
120106
'
121107

122108
test_expect_success 'setup: non-initial commit' '

0 commit comments

Comments
 (0)