Skip to content

Commit 153e0d7

Browse files
committed
Merge branch 'jk/add-i-use-pathspecs'
"git add -p <pathspec>" unnecessarily expanded the pathspec to a list of individual files that matches the pathspec by running "git ls-files <pathspec>", before feeding it to "git diff-index" to see which paths have changes, because historically the pathspec language supported by "diff-index" was weaker. These days they are equivalent and there is no reason to internally expand it. This helps both performance and avoids command line argument limit on some platforms. * jk/add-i-use-pathspecs: add--interactive: do not expand pathspecs with ls-files
2 parents 2af882b + 7288e12 commit 153e0d7

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

git-add--interactive.perl

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -275,20 +275,11 @@ sub list_modified {
275275
my ($only) = @_;
276276
my (%data, @return);
277277
my ($add, $del, $adddel, $file);
278-
my @tracked = ();
279-
280-
if (@ARGV) {
281-
@tracked = map {
282-
chomp $_;
283-
unquote_path($_);
284-
} run_cmd_pipe(qw(git ls-files --), @ARGV);
285-
return if (!@tracked);
286-
}
287278

288279
my $reference = get_diff_reference($patch_mode_revision);
289280
for (run_cmd_pipe(qw(git diff-index --cached
290281
--numstat --summary), $reference,
291-
'--', @tracked)) {
282+
'--', @ARGV)) {
292283
if (($add, $del, $file) =
293284
/^([-\d]+) ([-\d]+) (.*)/) {
294285
my ($change, $bin);
@@ -313,7 +304,7 @@ sub list_modified {
313304
}
314305
}
315306

316-
for (run_cmd_pipe(qw(git diff-files --numstat --summary --raw --), @tracked)) {
307+
for (run_cmd_pipe(qw(git diff-files --numstat --summary --raw --), @ARGV)) {
317308
if (($add, $del, $file) =
318309
/^([-\d]+) ([-\d]+) (.*)/) {
319310
$file = unquote_path($file);

t/t3701-add-interactive.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,4 +412,47 @@ test_expect_success 'patch-mode via -i prompts for files' '
412412
test_cmp expect actual
413413
'
414414

415+
test_expect_success 'add -p handles globs' '
416+
git reset --hard &&
417+
418+
mkdir -p subdir &&
419+
echo base >one.c &&
420+
echo base >subdir/two.c &&
421+
git add "*.c" &&
422+
git commit -m base &&
423+
424+
echo change >one.c &&
425+
echo change >subdir/two.c &&
426+
git add -p "*.c" <<-\EOF &&
427+
y
428+
y
429+
EOF
430+
431+
cat >expect <<-\EOF &&
432+
one.c
433+
subdir/two.c
434+
EOF
435+
git diff --cached --name-only >actual &&
436+
test_cmp expect actual
437+
'
438+
439+
test_expect_success 'add -p does not expand argument lists' '
440+
git reset --hard &&
441+
442+
echo content >not-changed &&
443+
git add not-changed &&
444+
git commit -m "add not-changed file" &&
445+
446+
echo change >file &&
447+
GIT_TRACE=$(pwd)/trace.out git add -p . <<-\EOF &&
448+
y
449+
EOF
450+
451+
# we know that "file" must be mentioned since we actually
452+
# update it, but we want to be sure that our "." pathspec
453+
# was not expanded into the argument list of any command.
454+
# So look only for "not-changed".
455+
! grep not-changed trace.out
456+
'
457+
415458
test_done

0 commit comments

Comments
 (0)