mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-16 04:07:36 -05:00
Merge branch 'td/ls-files-pathspec-prefilter' into jch
`git ls-files --modified` and `git ls-files --deleted` have been optimized to filter with pathspec before calling lstat() when there is only a single pathspec item, avoiding unnecessary filesystem access for entries that will not be shown. * td/ls-files-pathspec-prefilter: ls-files: filter pathspec before lstat
This commit is contained in:
@@ -453,6 +453,17 @@ static void show_files(struct repository *repo, struct dir_struct *dir)
|
||||
continue;
|
||||
if (ce_skip_worktree(ce))
|
||||
continue;
|
||||
/*
|
||||
* match_pathspec() is linear in pathspec.nr, so prefilter only
|
||||
* the single-pathspec case. Only entries shown by show_ce()
|
||||
* satisfy --error-unmatch.
|
||||
*/
|
||||
if (pathspec.nr == 1 &&
|
||||
!match_pathspec(repo->index, &pathspec, fullname.buf,
|
||||
fullname.len, max_prefix_len, NULL,
|
||||
S_ISDIR(ce->ce_mode) ||
|
||||
S_ISGITLINK(ce->ce_mode)))
|
||||
continue;
|
||||
stat_err = lstat(fullname.buf, &st);
|
||||
if (stat_err && (errno != ENOENT && errno != ENOTDIR))
|
||||
error_errno("cannot lstat '%s'", fullname.buf);
|
||||
|
||||
@@ -1141,6 +1141,7 @@ benchmarks = [
|
||||
'perf/p1500-graph-walks.sh',
|
||||
'perf/p1501-rev-parse-oneline.sh',
|
||||
'perf/p2000-sparse-operations.sh',
|
||||
'perf/p3010-ls-files.sh',
|
||||
'perf/p3400-rebase.sh',
|
||||
'perf/p3404-rebase-interactive.sh',
|
||||
'perf/p4000-diff-algorithms.sh',
|
||||
|
||||
31
t/perf/p3010-ls-files.sh
Executable file
31
t/perf/p3010-ls-files.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='Tests ls-files worktree performance'
|
||||
|
||||
. ./perf-lib.sh
|
||||
|
||||
test_perf_large_repo
|
||||
test_checkout_worktree
|
||||
|
||||
test_expect_success 'select a zero-prefix pathspec' '
|
||||
tracked_file=$(git ls-files | sed -n 1p) &&
|
||||
test -n "$tracked_file" &&
|
||||
pathspec="?${tracked_file#?}" &&
|
||||
test_export pathspec
|
||||
'
|
||||
|
||||
test_perf 'ls-files --deleted with pathspec' '
|
||||
git -c core.fsmonitor=false ls-files --deleted \
|
||||
-- "$pathspec" >/dev/null
|
||||
'
|
||||
|
||||
test_perf 'ls-files --deleted with all-matching pathspec' '
|
||||
git -c core.fsmonitor=false ls-files --deleted -- "*" >/dev/null
|
||||
'
|
||||
|
||||
test_perf 'ls-files --modified with pathspec' '
|
||||
git -c core.fsmonitor=false ls-files --modified \
|
||||
-- "$pathspec" >/dev/null
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -124,4 +124,22 @@ test_expect_success 'validate git ls-files -m output.' '
|
||||
test_cmp .expected .output
|
||||
'
|
||||
|
||||
test_expect_success 'worktree modes honor wildcard pathspecs' '
|
||||
cat >.expected <<-\EOF &&
|
||||
path2/file2
|
||||
path3/file3
|
||||
EOF
|
||||
git ls-files --deleted -- "path?/file?" >.output &&
|
||||
test_cmp .expected .output &&
|
||||
|
||||
cat >.expected <<-\EOF &&
|
||||
path7
|
||||
path8
|
||||
EOF
|
||||
git ls-files --modified --error-unmatch -- "path[78]" >.output &&
|
||||
test_cmp .expected .output &&
|
||||
|
||||
test_must_fail git ls-files --modified --error-unmatch -- path10
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
Reference in New Issue
Block a user