]> git.ipfire.org Git - thirdparty/git.git/blob - t/perf/p5303-many-packs.sh
Merge branch 'ab/grep-pcre-invalid-utf8'
[thirdparty/git.git] / t / perf / p5303-many-packs.sh
1 #!/bin/sh
2
3 test_description='performance with large numbers of packs'
4 . ./perf-lib.sh
5
6 test_perf_large_repo
7
8 # A real many-pack situation would probably come from having a lot of pushes
9 # over time. We don't know how big each push would be, but we can fake it by
10 # just walking the first-parent chain and having every 5 commits be their own
11 # "push". This isn't _entirely_ accurate, as real pushes would have some
12 # duplicate objects due to thin-pack fixing, but it's a reasonable
13 # approximation.
14 #
15 # And then all of the rest of the objects can go in a single packfile that
16 # represents the state before any of those pushes (actually, we'll generate
17 # that first because in such a setup it would be the oldest pack, and we sort
18 # the packs by reverse mtime inside git).
19 repack_into_n () {
20 rm -rf staging &&
21 mkdir staging &&
22
23 git rev-list --first-parent HEAD |
24 perl -e '
25 my $n = shift;
26 while (<>) {
27 last unless @commits < $n;
28 push @commits, $_ if $. % 5 == 1;
29 }
30 print reverse @commits;
31 ' "$1" >pushes
32
33 # create base packfile
34 head -n 1 pushes |
35 git pack-objects --delta-base-offset --revs staging/pack
36
37 # and then incrementals between each pair of commits
38 last= &&
39 while read rev
40 do
41 if test -n "$last"; then
42 {
43 echo "$rev" &&
44 echo "^$last"
45 } |
46 git pack-objects --delta-base-offset --revs \
47 staging/pack || return 1
48 fi
49 last=$rev
50 done <pushes &&
51
52 # and install the whole thing
53 rm -f .git/objects/pack/* &&
54 mv staging/* .git/objects/pack/
55 }
56
57 # Pretend we just have a single branch and no reflogs, and that everything is
58 # in objects/pack; that makes our fake pack-building via repack_into_n()
59 # much simpler.
60 test_expect_success 'simplify reachability' '
61 tip=$(git rev-parse --verify HEAD) &&
62 git for-each-ref --format="option no-deref%0adelete %(refname)" |
63 git update-ref --stdin &&
64 rm -rf .git/logs &&
65 git update-ref refs/heads/master $tip &&
66 git symbolic-ref HEAD refs/heads/master &&
67 git repack -ad
68 '
69
70 for nr_packs in 1 50 1000
71 do
72 test_expect_success "create $nr_packs-pack scenario" '
73 repack_into_n $nr_packs
74 '
75
76 test_perf "rev-list ($nr_packs)" '
77 git rev-list --objects --all >/dev/null
78 '
79
80 test_perf "abbrev-commit ($nr_packs)" '
81 git rev-list --abbrev-commit HEAD >/dev/null
82 '
83
84 # This simulates the interesting part of the repack, which is the
85 # actual pack generation, without smudging the on-disk setup
86 # between trials.
87 test_perf "repack ($nr_packs)" '
88 GIT_TEST_FULL_IN_PACK_ARRAY=1 \
89 git pack-objects --keep-true-parents \
90 --honor-pack-keep --non-empty --all \
91 --reflog --indexed-objects --delta-base-offset \
92 --stdout </dev/null >/dev/null
93 '
94 done
95
96 # Measure pack loading with 10,000 packs.
97 test_expect_success 'generate lots of packs' '
98 for i in $(test_seq 10000); do
99 echo "blob"
100 echo "data <<EOF"
101 echo "blob $i"
102 echo "EOF"
103 echo "checkpoint"
104 done |
105 git -c fastimport.unpackLimit=0 fast-import
106 '
107
108 # The purpose of this test is to evaluate load time for a large number
109 # of packs while doing as little other work as possible.
110 test_perf "load 10,000 packs" '
111 git rev-parse --verify "HEAD^{commit}"
112 '
113
114 test_done