Re: [PATCH 2/2] pretty: add merge and exclude options to %(describe)
- From
René Scharfe. <l.s.r@web.de>
- Date
- Mar 6, 2021, 16:18 UTC
- Message-ID
- <a28592c5-4a70-1ea8-fd73-959e28b4278d@web.de>
- In-Reply-To
- <30f78fce-fe1a-0a50-fa8c-e6fe14a03bf3@web.de>
Am 02.03.21 um 17:00 schrieb René Scharfe.:
Show 13 quoted lines
> Am 28.02.21 um 16:41 schrieb Ævar Arnfjörð Bjarmason: >> Instead of taking the trouble of putting a limit in the >> pretty_print_context so we don't call it N times for the same commit, >> why not just put the strbuf with the result in that same struct? >> >> Then you can have it millions of times, and it won't be any more >> expensive than the other existing %(format) specifiers (actually cheaper >> than most). > > Each %(describe) placeholder can have a unique set of match or exclude > arguments. Caching them all would increase the strength of a DoS > attack. Caching a few of them would be OK, but is ineffective in > reducing the strength of the attack.
The script at the bottom creates archives that illustrate the issue. On a repo generated with parameter 10 (10 files with 10 $Format:...$ with 10 %(describe) placeholders, so 1000 total), I get the following number with v2.30.1, which ignores %(describe):
Benchmark #1: git archive HEAD Time (mean ± σ): 2.2 ms ± 0.2 ms [User: 0.9 ms, System: 1.0 ms] Range (min … max): 1.8 ms … 2.8 ms 705 runs
Warning: Command took less than 5 ms to complete. Results might be inaccurate.
The version in next expands all placeholders and takes three orders of magnitude longer:
Benchmark #1: git archive HEAD Time (mean ± σ): 2.300 s ± 0.003 s [User: 819.0 ms, System: 1200.0 ms] Range (min … max): 2.293 s … 2.305 s 10 runs
The proposed patch to expand only a single placeholder gets the runtime back under control:
Benchmark #1: git archive HEAD Time (mean ± σ): 4.7 ms ± 0.3 ms [User: 1.8 ms, System: 2.2 ms] Range (min … max): 4.2 ms … 7.0 ms 451 runs
Warning: Command took less than 5 ms to complete. Results might be inaccurate.
Using parameter 100 takes about a second to create the repo, but the git archive version in next already needs longer to tar it up than I'm willing to wait.
#!/bin/sh
n=$1
mkdir $n
cd $n
git init
for i in $(seq $n)
do
awk -v i=$i -v n=$n 'END {
for (j = 0; j < n; j++) {
print "$Format:"
for (k = 0; k < n; k++) {
print "%(describe:exclude=x-" i "-" j "-" k ")"
}
print "$"
}
}' </dev/null >"file$i"
done
git add file*
echo "file* export-subst" >.gitattributes
git add .gitattributes
git commit -m initial
for tagno in $(seq $n)
do
git tag -m "$tagno" "tag$tagno"
done