Am 02.03.21 um 17:00 schrieb René Scharfe.: > 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