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