]>
Commit | Line | Data |
---|---|---|
1 | #!/bin/sh | |
2 | ||
3 | test_description='basic git gc tests | |
4 | ' | |
5 | ||
6 | . ./test-lib.sh | |
7 | . "$TEST_DIRECTORY"/lib-terminal.sh | |
8 | ||
9 | test_expect_success 'setup' ' | |
10 | # do not let the amount of physical memory affects gc | |
11 | # behavior, make sure we always pack everything to one pack by | |
12 | # default | |
13 | git config gc.bigPackThreshold 2g && | |
14 | ||
15 | # These are simply values which, when hashed as a blob with a newline, | |
16 | # produce a hash where the first byte is 0x17 in their respective | |
17 | # algorithms. | |
18 | test_oid_cache <<-EOF | |
19 | obj1 sha1:263 | |
20 | obj1 sha256:34 | |
21 | ||
22 | obj2 sha1:410 | |
23 | obj2 sha256:174 | |
24 | ||
25 | obj3 sha1:523 | |
26 | obj3 sha256:313 | |
27 | ||
28 | obj4 sha1:790 | |
29 | obj4 sha256:481 | |
30 | EOF | |
31 | ' | |
32 | ||
33 | test_expect_success 'gc empty repository' ' | |
34 | git gc | |
35 | ' | |
36 | ||
37 | test_expect_success 'gc does not leave behind pid file' ' | |
38 | git gc && | |
39 | test_path_is_missing .git/gc.pid | |
40 | ' | |
41 | ||
42 | test_expect_success 'gc --gobbledegook' ' | |
43 | test_expect_code 129 git gc --nonsense 2>err && | |
44 | test_i18ngrep "[Uu]sage: git gc" err | |
45 | ' | |
46 | ||
47 | test_expect_success 'gc -h with invalid configuration' ' | |
48 | mkdir broken && | |
49 | ( | |
50 | cd broken && | |
51 | git init && | |
52 | echo "[gc] pruneexpire = CORRUPT" >>.git/config && | |
53 | test_expect_code 129 git gc -h >usage 2>&1 | |
54 | ) && | |
55 | test_i18ngrep "[Uu]sage" broken/usage | |
56 | ' | |
57 | ||
58 | test_expect_success 'gc is not aborted due to a stale symref' ' | |
59 | git init remote && | |
60 | ( | |
61 | cd remote && | |
62 | test_commit initial && | |
63 | git clone . ../client && | |
64 | git branch -m develop && | |
65 | cd ../client && | |
66 | git fetch --prune && | |
67 | git gc | |
68 | ) | |
69 | ' | |
70 | ||
71 | test_expect_success 'gc --keep-largest-pack' ' | |
72 | test_create_repo keep-pack && | |
73 | ( | |
74 | cd keep-pack && | |
75 | test_commit one && | |
76 | test_commit two && | |
77 | test_commit three && | |
78 | git gc && | |
79 | ( cd .git/objects/pack && ls *.pack ) >pack-list && | |
80 | test_line_count = 1 pack-list && | |
81 | cp pack-list base-pack-list && | |
82 | test_commit four && | |
83 | git repack -d && | |
84 | test_commit five && | |
85 | git repack -d && | |
86 | ( cd .git/objects/pack && ls *.pack ) >pack-list && | |
87 | test_line_count = 3 pack-list && | |
88 | git gc --keep-largest-pack && | |
89 | ( cd .git/objects/pack && ls *.pack ) >pack-list && | |
90 | test_line_count = 2 pack-list && | |
91 | awk "/^P /{print \$2}" <.git/objects/info/packs >pack-info && | |
92 | test_line_count = 2 pack-info && | |
93 | test_path_is_file .git/objects/pack/$(cat base-pack-list) && | |
94 | git fsck | |
95 | ) | |
96 | ' | |
97 | ||
98 | test_expect_success 'auto gc with too many loose objects does not attempt to create bitmaps' ' | |
99 | test_config gc.auto 3 && | |
100 | test_config gc.autodetach false && | |
101 | test_config pack.writebitmaps true && | |
102 | # We need to create two object whose sha1s start with 17 | |
103 | # since this is what git gc counts. As it happens, these | |
104 | # two blobs will do so. | |
105 | test_commit "$(test_oid obj1)" && | |
106 | test_commit "$(test_oid obj2)" && | |
107 | # Our first gc will create a pack; our second will create a second pack | |
108 | git gc --auto && | |
109 | ls .git/objects/pack/pack-*.pack | sort >existing_packs && | |
110 | test_commit "$(test_oid obj3)" && | |
111 | test_commit "$(test_oid obj4)" && | |
112 | ||
113 | git gc --auto 2>err && | |
114 | test_i18ngrep ! "^warning:" err && | |
115 | ls .git/objects/pack/pack-*.pack | sort >post_packs && | |
116 | comm -1 -3 existing_packs post_packs >new && | |
117 | comm -2 -3 existing_packs post_packs >del && | |
118 | test_line_count = 0 del && # No packs are deleted | |
119 | test_line_count = 1 new # There is one new pack | |
120 | ' | |
121 | ||
122 | test_expect_success 'gc --no-quiet' ' | |
123 | GIT_PROGRESS_DELAY=0 git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr && | |
124 | test_must_be_empty stdout && | |
125 | test_i18ngrep "Computing commit graph generation numbers" stderr | |
126 | ' | |
127 | ||
128 | test_expect_success TTY 'with TTY: gc --no-quiet' ' | |
129 | test_terminal env GIT_PROGRESS_DELAY=0 \ | |
130 | git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr && | |
131 | test_must_be_empty stdout && | |
132 | test_i18ngrep "Enumerating objects" stderr && | |
133 | test_i18ngrep "Computing commit graph generation numbers" stderr | |
134 | ' | |
135 | ||
136 | test_expect_success 'gc --quiet' ' | |
137 | git -c gc.writeCommitGraph=true gc --quiet >stdout 2>stderr && | |
138 | test_must_be_empty stdout && | |
139 | test_must_be_empty stderr | |
140 | ' | |
141 | ||
142 | test_expect_success 'gc.reflogExpire{Unreachable,}=never skips "expire" via "gc"' ' | |
143 | test_config gc.reflogExpire never && | |
144 | test_config gc.reflogExpireUnreachable never && | |
145 | ||
146 | GIT_TRACE=$(pwd)/trace.out git gc && | |
147 | ||
148 | # Check that git-pack-refs is run as a sanity check (done via | |
149 | # gc_before_repack()) but that git-expire is not. | |
150 | grep -E "^trace: (built-in|exec|run_command): git pack-refs --" trace.out && | |
151 | ! grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out | |
152 | ' | |
153 | ||
154 | test_expect_success 'one of gc.reflogExpire{Unreachable,}=never does not skip "expire" via "gc"' ' | |
155 | >trace.out && | |
156 | test_config gc.reflogExpire never && | |
157 | GIT_TRACE=$(pwd)/trace.out git gc && | |
158 | grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out | |
159 | ' | |
160 | ||
161 | run_and_wait_for_auto_gc () { | |
162 | # We read stdout from gc for the side effect of waiting until the | |
163 | # background gc process exits, closing its fd 9. Furthermore, the | |
164 | # variable assignment from a command substitution preserves the | |
165 | # exit status of the main gc process. | |
166 | # Note: this fd trickery doesn't work on Windows, but there is no | |
167 | # need to, because on Win the auto gc always runs in the foreground. | |
168 | doesnt_matter=$(git gc --auto 9>&1) | |
169 | } | |
170 | ||
171 | test_expect_success 'background auto gc does not run if gc.log is present and recent but does if it is old' ' | |
172 | test_commit foo && | |
173 | test_commit bar && | |
174 | git repack && | |
175 | test_config gc.autopacklimit 1 && | |
176 | test_config gc.autodetach true && | |
177 | echo fleem >.git/gc.log && | |
178 | git gc --auto 2>err && | |
179 | test_i18ngrep "^warning:" err && | |
180 | test_config gc.logexpiry 5.days && | |
181 | test-tool chmtime =-345600 .git/gc.log && | |
182 | git gc --auto && | |
183 | test_config gc.logexpiry 2.days && | |
184 | run_and_wait_for_auto_gc && | |
185 | ls .git/objects/pack/pack-*.pack >packs && | |
186 | test_line_count = 1 packs | |
187 | ' | |
188 | ||
189 | test_expect_success 'background auto gc respects lock for all operations' ' | |
190 | # make sure we run a background auto-gc | |
191 | test_commit make-pack && | |
192 | git repack && | |
193 | test_config gc.autopacklimit 1 && | |
194 | test_config gc.autodetach true && | |
195 | ||
196 | # create a ref whose loose presence we can use to detect a pack-refs run | |
197 | git update-ref refs/heads/should-be-loose HEAD && | |
198 | test_path_is_file .git/refs/heads/should-be-loose && | |
199 | ||
200 | # now fake a concurrent gc that holds the lock; we can use our | |
201 | # shell pid so that it looks valid. | |
202 | hostname=$(hostname || echo unknown) && | |
203 | shell_pid=$$ && | |
204 | if test_have_prereq MINGW && test -f /proc/$shell_pid/winpid | |
205 | then | |
206 | # In Git for Windows, Bash (actually, the MSYS2 runtime) has a | |
207 | # different idea of PIDs than git.exe (actually Windows). Use | |
208 | # the Windows PID in this case. | |
209 | shell_pid=$(cat /proc/$shell_pid/winpid) | |
210 | fi && | |
211 | printf "%d %s" "$shell_pid" "$hostname" >.git/gc.pid && | |
212 | ||
213 | # our gc should exit zero without doing anything | |
214 | run_and_wait_for_auto_gc && | |
215 | test_path_is_file .git/refs/heads/should-be-loose | |
216 | ' | |
217 | ||
218 | # DO NOT leave a detached auto gc process running near the end of the | |
219 | # test script: it can run long enough in the background to racily | |
220 | # interfere with the cleanup in 'test_done'. | |
221 | ||
222 | test_done |