fdb2fa87978197762806a4bb0d1fbcf7af169fb8
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 &&
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.
37test_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.
55test_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.
73test_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.
88test_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.
103test_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 '
113test_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 '
124# The heuristic called by guess_line_blames() tries to find the size of a
125# blame_entry 'e' in the parent's address space. Those calculations need to
126# check for negative or zero values for when a blame entry is completely outside
127# the window of the parent's version of a file.
128#
129# This happens when one commit adds several lines (commit B below). A later
130# commit (C) changes one line in the middle of B's change. Commit C gets blamed
131# for its change, and that breaks up B's change into multiple blame entries.
132# When processing B, one of the blame_entries is outside A's window (which was
133# zero - it had no lines added on its side of the diff).
134#
135# A--B--C, ignore B to test the ignore heuristic's boundary checks.
136test_expect_success ignored_chunk_negative_parent_size '
137 rm -rf .git/ &&
138 git init &&
139
140 test_write_lines L1 L2 L7 L8 L9 >file &&
141 git add file &&
142 test_tick &&
143 git commit -m A &&
144 git tag A &&
145
146 test_write_lines L1 L2 L3 L4 L5 L6 L7 L8 L9 >file &&
147 git add file &&
148 test_tick &&
149 git commit -m B &&
150 git tag B &&
151
152 test_write_lines L1 L2 L3 L4 xxx L6 L7 L8 L9 >file &&
153 git add file &&
154 test_tick &&
155 git commit -m C &&
156 git tag C &&
157
158 git blame file --ignore-rev B >blame_raw
159 '
160
161# Resetting the repo and creating:
162#
163# A--B--M
164# \ /
165# C-+
166#
167# 'A' creates a file. B changes line 1, and C changes line 9. M merges.
168test_expect_success ignore_merge '
169 rm -rf .git/ &&
170 git init &&
171
172 test_write_lines L1 L2 L3 L4 L5 L6 L7 L8 L9 >file &&
173 git add file &&
174 test_tick &&
175 git commit -m A &&
176 git tag A &&
177
178 test_write_lines BB L2 L3 L4 L5 L6 L7 L8 L9 >file &&
179 git add file &&
180 test_tick &&
181 git commit -m B &&
182 git tag B &&
183
184 git reset --hard A &&
185 test_write_lines L1 L2 L3 L4 L5 L6 L7 L8 CC >file &&
186 git add file &&
187 test_tick &&
188 git commit -m C &&
189 git tag C &&
190
191 test_merge M B &&
192 git blame --line-porcelain file --ignore-rev M >blame_raw &&
193
194 grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
195 git rev-parse B >expect &&
196 test_cmp expect actual &&
197
198 grep -E "^[0-9a-f]+ [0-9]+ 9" blame_raw | sed -e "s/ .*//" >actual &&
199 git rev-parse C >expect &&
200 test_cmp expect actual
201 '
202
203test_done