mirror of
https://github.com/git/git.git
synced 2026-09-28 17:12:46 +02:00
`git stash -p` prepares the interactive selection by creating a temporary index at HEAD, switching `GIT_INDEX_FILE` to it, and then running the `add -p` machinery. That temporary index was created by running `git read-tree HEAD`. The resulting index had no useful cached stat data or fsmonitor-valid bits from the real index. When `run_add_p()` refreshed that temporary index before showing the first prompt, it could end up lstat(2)-ing every tracked file, even in a repository where `git diff` and `git restore -p` can use fsmonitor to avoid that work. Create the temporary index in-process instead. Use `unpack_trees()` to reset the real index contents to HEAD while writing the result to the temporary index path. For paths whose index entries already match HEAD, `oneway_merge()` reuses the existing cache entries, preserving their cached stat data and `CE_FSMONITOR_VALID` state. This makes the refresh performed by `run_add_p()` behave like the one used by `git restore -p`: unchanged paths can be skipped via fsmonitor instead of being scanned again. In a 206k file repository with `core.fsmonitor` enabled and a one-line change in one file, time to first prompt dropped from 34.774 seconds to 0.659 seconds. The new perf test file demonstrates similar improvements, with maen times for without- and with-fsmonitor cases dropping from 6.90 and 6.83 seconds to 0.55 and 0.28 seconds, respectively. Signed-off-by: Adam Johnson <me@adamj.eu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
44 lines
962 B
Bash
Executable File
44 lines
962 B
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description="Performance tests for git stash -p"
|
|
|
|
. ./perf-lib.sh
|
|
|
|
test_perf_fresh_repo
|
|
|
|
test_expect_success "setup" '
|
|
mkdir files &&
|
|
test_seq 1 100000 | while read i; do
|
|
echo "content $i" >files/$i.txt || return 1
|
|
done &&
|
|
git add files/ &&
|
|
git commit -q -m "add tracked files" &&
|
|
echo modified >files/1.txt
|
|
'
|
|
|
|
test_perf "stash -p, no fsmonitor" \
|
|
--setup 'echo modified >files/1.txt' '
|
|
printf "q\n" | git stash -p >/dev/null 2>&1 || true
|
|
'
|
|
|
|
if test_have_prereq FSMONITOR_DAEMON
|
|
then
|
|
test_expect_success "enable builtin fsmonitor" '
|
|
git config core.fsmonitor true &&
|
|
git fsmonitor--daemon start &&
|
|
git update-index --fsmonitor &&
|
|
git status >/dev/null 2>&1
|
|
'
|
|
|
|
test_perf "stash -p, builtin fsmonitor" \
|
|
--setup 'echo modified >files/1.txt && git status >/dev/null 2>&1' '
|
|
printf "q\n" | git stash -p >/dev/null 2>&1 || true
|
|
'
|
|
|
|
test_expect_success "stop builtin fsmonitor" '
|
|
git fsmonitor--daemon stop
|
|
'
|
|
fi
|
|
|
|
test_done
|