]>
Commit | Line | Data |
---|---|---|
ae3f36de BR |
1 | #!/bin/sh |
2 | ||
3 | test_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. | |
10 | test_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 |
38 | test_expect_success 'validate --ignore-rev' ' | |
39 | test_must_fail git blame --ignore-rev X^{tree} file | |
40 | ' | |
ae3f36de | 41 | |
610e2b92 JH |
42 | # Ensure bogus --ignore-revs-file requests are caught |
43 | test_expect_success 'validate --ignore-revs-file' ' | |
44 | git rev-parse X^{tree} >ignore_x && | |
45 | test_must_fail git blame --ignore-revs-file ignore_x file | |
f58931c8 | 46 | ' |
ae3f36de | 47 | |
610e2b92 JH |
48 | for I in X XT |
49 | do | |
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 | ' | |
64 | done | |
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. | |
72 | test_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. | |
90 | test_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. | |
105 | test_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. | |
120 | test_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 | ' | |
130 | test_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. | |
147 | test_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 | |
168 | test_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. | |
199 | test_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. | |
224 | test_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. | |
256 | test_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 | |
291 | test_done |