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