]> git.ipfire.org Git - thirdparty/git.git/blame - t/t8013-blame-ignore-revs.sh
blame: silently ignore invalid ignore file objects
[thirdparty/git.git] / t / t8013-blame-ignore-revs.sh
CommitLineData
ae3f36de
BR
1#!/bin/sh
2
3test_description='ignore revisions when blaming'
4. ./test-lib.sh
5
6# Creates:
7# A--B--X
8# A added line 1 and B added line 2. X makes changes to those lines. Sanity
9# check that X is blamed for both lines.
10test_expect_success setup '
11 test_commit A file line1 &&
12
13 echo line2 >>file &&
14 git add file &&
15 test_tick &&
16 git commit -m B &&
17 git tag B &&
18
19 test_write_lines line-one line-two >file &&
20 git add file &&
21 test_tick &&
22 git commit -m X &&
23 git tag X &&
610e2b92 24 git tag -a -m "X (annotated)" XT &&
ae3f36de
BR
25
26 git blame --line-porcelain file >blame_raw &&
27
28 grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
29 git rev-parse X >expect &&
30 test_cmp expect actual &&
31
32 grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
33 git rev-parse X >expect &&
34 test_cmp expect actual
f58931c8 35'
ae3f36de 36
610e2b92
JH
37# Ensure bogus --ignore-rev requests are caught
38test_expect_success 'validate --ignore-rev' '
39 test_must_fail git blame --ignore-rev X^{tree} file
40'
ae3f36de 41
c714d058 42# Ensure bogus --ignore-revs-file requests are silently accepted
610e2b92
JH
43test_expect_success 'validate --ignore-revs-file' '
44 git rev-parse X^{tree} >ignore_x &&
c714d058 45 git blame --ignore-revs-file ignore_x file
f58931c8 46'
ae3f36de 47
610e2b92
JH
48for I in X XT
49do
50 # Ignore X (or XT), make sure A is blamed for line 1 and B for line 2.
51 # Giving X (i.e. commit) and XT (i.e. annotated tag to commit) should
52 # produce the same result.
53 test_expect_success "ignore_rev_changing_lines ($I)" '
54 git blame --line-porcelain --ignore-rev $I file >blame_raw &&
55
56 grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
57 git rev-parse A >expect &&
58 test_cmp expect actual &&
59
60 grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
61 git rev-parse B >expect &&
62 test_cmp expect actual
63 '
64done
65
ae3f36de
BR
66# For ignored revs that have added 'unblamable' lines, attribute those to the
67# ignored commit.
68# A--B--X--Y
69# Where Y changes lines 1 and 2, and adds lines 3 and 4. The added lines ought
70# to have nothing in common with "line-one" or "line-two", to keep any
71# heuristics from matching them with any lines in the parent.
72test_expect_success ignore_rev_adding_unblamable_lines '
73 test_write_lines line-one-change line-two-changed y3 y4 >file &&
74 git add file &&
75 test_tick &&
76 git commit -m Y &&
77 git tag Y &&
78
79 git rev-parse Y >expect &&
80 git blame --line-porcelain file --ignore-rev Y >blame_raw &&
81
82 grep -E "^[0-9a-f]+ [0-9]+ 3" blame_raw | sed -e "s/ .*//" >actual &&
83 test_cmp expect actual &&
84
85 grep -E "^[0-9a-f]+ [0-9]+ 4" blame_raw | sed -e "s/ .*//" >actual &&
86 test_cmp expect actual
f58931c8 87'
ae3f36de
BR
88
89# Ignore X and Y, both in separate files. Lines 1 == A, 2 == B.
90test_expect_success ignore_revs_from_files '
91 git rev-parse X >ignore_x &&
92 git rev-parse Y >ignore_y &&
93 git blame --line-porcelain file --ignore-revs-file ignore_x --ignore-revs-file ignore_y >blame_raw &&
94
95 grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
96 git rev-parse A >expect &&
97 test_cmp expect actual &&
98
99 grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
100 git rev-parse B >expect &&
101 test_cmp expect actual
f58931c8 102'
ae3f36de
BR
103
104# Ignore X from the config option, Y from a file.
105test_expect_success ignore_revs_from_configs_and_files '
106 git config --add blame.ignoreRevsFile ignore_x &&
107 git blame --line-porcelain file --ignore-revs-file ignore_y >blame_raw &&
108
109 grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
110 git rev-parse A >expect &&
111 test_cmp expect actual &&
112
113 grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
114 git rev-parse B >expect &&
115 test_cmp expect actual
f58931c8 116'
ae3f36de
BR
117
118# Override blame.ignoreRevsFile (ignore_x) with an empty string. X should be
119# blamed now for lines 1 and 2, since we are no longer ignoring X.
120test_expect_success override_ignore_revs_file '
121 git blame --line-porcelain file --ignore-revs-file "" --ignore-revs-file ignore_y >blame_raw &&
122 git rev-parse X >expect &&
123
124 grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
125 test_cmp expect actual &&
126
127 grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
128 test_cmp expect actual
129 '
130test_expect_success bad_files_and_revs '
131 test_must_fail git blame file --ignore-rev NOREV 2>err &&
132 test_i18ngrep "cannot find revision NOREV to ignore" err &&
133
134 test_must_fail git blame file --ignore-revs-file NOFILE 2>err &&
135 test_i18ngrep "could not open.*: NOFILE" err &&
136
137 echo NOREV >ignore_norev &&
138 test_must_fail git blame file --ignore-revs-file ignore_norev 2>err &&
139 test_i18ngrep "invalid object name: NOREV" err
f58931c8 140'
8934ac8c
BR
141
142# For ignored revs that have added 'unblamable' lines, mark those lines with a
143# '*'
144# A--B--X--Y
145# Lines 3 and 4 are from Y and unblamable. This was set up in
146# ignore_rev_adding_unblamable_lines.
147test_expect_success mark_unblamable_lines '
148 git config --add blame.markUnblamableLines true &&
149
150 git blame --ignore-rev Y file >blame_raw &&
151 echo "*" >expect &&
152
153 sed -n "3p" blame_raw | cut -c1 >actual &&
154 test_cmp expect actual &&
155
156 sed -n "4p" blame_raw | cut -c1 >actual &&
157 test_cmp expect actual
f58931c8 158'
8934ac8c
BR
159
160# Commit Z will touch the first two lines. Y touched all four.
161# A--B--X--Y--Z
162# The blame output when ignoring Z should be:
163# ?Y ... 1)
164# ?Y ... 2)
165# Y ... 3)
166# Y ... 4)
167# We're checking only the first character
168test_expect_success mark_ignored_lines '
169 git config --add blame.markIgnoredLines true &&
170
171 test_write_lines line-one-Z line-two-Z y3 y4 >file &&
172 git add file &&
173 test_tick &&
174 git commit -m Z &&
175 git tag Z &&
176
177 git blame --ignore-rev Z file >blame_raw &&
178 echo "?" >expect &&
179
180 sed -n "1p" blame_raw | cut -c1 >actual &&
181 test_cmp expect actual &&
182
183 sed -n "2p" blame_raw | cut -c1 >actual &&
184 test_cmp expect actual &&
185
186 sed -n "3p" blame_raw | cut -c1 >actual &&
187 ! test_cmp expect actual &&
188
189 sed -n "4p" blame_raw | cut -c1 >actual &&
190 ! test_cmp expect actual
f58931c8 191'
8934ac8c
BR
192
193# For ignored revs that added 'unblamable' lines and more recent commits changed
194# the blamable lines, mark the unblamable lines with a
195# '*'
196# A--B--X--Y--Z
197# Lines 3 and 4 are from Y and unblamable, as set up in
198# ignore_rev_adding_unblamable_lines. Z changed lines 1 and 2.
199test_expect_success mark_unblamable_lines_intermediate '
200 git config --add blame.markUnblamableLines true &&
201
202 git blame --ignore-rev Y file >blame_raw 2>stderr &&
203 echo "*" >expect &&
204
205 sed -n "3p" blame_raw | cut -c1 >actual &&
206 test_cmp expect actual &&
207
208 sed -n "4p" blame_raw | cut -c1 >actual &&
209 test_cmp expect actual
f58931c8 210'
8934ac8c 211
ae3f36de
BR
212# The heuristic called by guess_line_blames() tries to find the size of a
213# blame_entry 'e' in the parent's address space. Those calculations need to
214# check for negative or zero values for when a blame entry is completely outside
215# the window of the parent's version of a file.
216#
217# This happens when one commit adds several lines (commit B below). A later
218# commit (C) changes one line in the middle of B's change. Commit C gets blamed
219# for its change, and that breaks up B's change into multiple blame entries.
220# When processing B, one of the blame_entries is outside A's window (which was
221# zero - it had no lines added on its side of the diff).
222#
223# A--B--C, ignore B to test the ignore heuristic's boundary checks.
224test_expect_success ignored_chunk_negative_parent_size '
225 rm -rf .git/ &&
226 git init &&
227
228 test_write_lines L1 L2 L7 L8 L9 >file &&
229 git add file &&
230 test_tick &&
231 git commit -m A &&
232 git tag A &&
233
234 test_write_lines L1 L2 L3 L4 L5 L6 L7 L8 L9 >file &&
235 git add file &&
236 test_tick &&
237 git commit -m B &&
238 git tag B &&
239
240 test_write_lines L1 L2 L3 L4 xxx L6 L7 L8 L9 >file &&
241 git add file &&
242 test_tick &&
243 git commit -m C &&
244 git tag C &&
245
246 git blame file --ignore-rev B >blame_raw
f58931c8 247'
ae3f36de
BR
248
249# Resetting the repo and creating:
250#
251# A--B--M
252# \ /
253# C-+
254#
255# 'A' creates a file. B changes line 1, and C changes line 9. M merges.
256test_expect_success ignore_merge '
257 rm -rf .git/ &&
258 git init &&
259
260 test_write_lines L1 L2 L3 L4 L5 L6 L7 L8 L9 >file &&
261 git add file &&
262 test_tick &&
263 git commit -m A &&
264 git tag A &&
265
266 test_write_lines BB L2 L3 L4 L5 L6 L7 L8 L9 >file &&
267 git add file &&
268 test_tick &&
269 git commit -m B &&
270 git tag B &&
271
272 git reset --hard A &&
273 test_write_lines L1 L2 L3 L4 L5 L6 L7 L8 CC >file &&
274 git add file &&
275 test_tick &&
276 git commit -m C &&
277 git tag C &&
278
279 test_merge M B &&
280 git blame --line-porcelain file --ignore-rev M >blame_raw &&
281
282 grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
283 git rev-parse B >expect &&
284 test_cmp expect actual &&
285
286 grep -E "^[0-9a-f]+ [0-9]+ 9" blame_raw | sed -e "s/ .*//" >actual &&
287 git rev-parse C >expect &&
288 test_cmp expect actual
f58931c8 289'
ae3f36de
BR
290
291test_done