| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='diff function context' |
| 4 | |
| 5 | . ./test-lib.sh |
| 6 | |
| 7 | dir="$TEST_DIRECTORY/t4051" |
| 8 | |
| 9 | commit_and_tag () { |
| 10 | tag=$1 && |
| 11 | shift && |
| 12 | git add "$@" && |
| 13 | test_tick && |
| 14 | git commit -m "$tag" && |
| 15 | git tag "$tag" |
| 16 | } |
| 17 | |
| 18 | first_context_line () { |
| 19 | awk ' |
| 20 | found {print; exit} |
| 21 | /^@@/ {found = 1} |
| 22 | ' |
| 23 | } |
| 24 | |
| 25 | last_context_line () { |
| 26 | sed -ne \$p |
| 27 | } |
| 28 | |
| 29 | check_diff () { |
| 30 | name=$1 |
| 31 | desc=$2 |
| 32 | options="-W $3" |
| 33 | |
| 34 | test_expect_success "$desc" ' |
| 35 | git diff $options "$name^" "$name" >"$name.diff" |
| 36 | ' |
| 37 | |
| 38 | test_expect_success ' diff applies' ' |
| 39 | test_when_finished "git reset --hard" && |
| 40 | git checkout --detach "$name^" && |
| 41 | git apply --index "$name.diff" && |
| 42 | git diff --exit-code "$name" |
| 43 | ' |
| 44 | } |
| 45 | |
| 46 | test_expect_success 'setup' ' |
| 47 | cat "$dir/includes.c" "$dir/dummy.c" "$dir/dummy.c" "$dir/hello.c" \ |
| 48 | "$dir/dummy.c" "$dir/dummy.c" >file.c && |
| 49 | commit_and_tag initial file.c && |
| 50 | |
| 51 | grep -v "delete me from hello" <file.c >file.c.new && |
| 52 | mv file.c.new file.c && |
| 53 | commit_and_tag changed_hello file.c && |
| 54 | |
| 55 | grep -v "delete me from includes" <file.c >file.c.new && |
| 56 | mv file.c.new file.c && |
| 57 | commit_and_tag changed_includes file.c && |
| 58 | |
| 59 | cat "$dir/appended1.c" >>file.c && |
| 60 | commit_and_tag appended file.c && |
| 61 | |
| 62 | cat "$dir/appended2.c" >>file.c && |
| 63 | commit_and_tag extended file.c && |
| 64 | |
| 65 | grep -v "Begin of second part" <file.c >file.c.new && |
| 66 | mv file.c.new file.c && |
| 67 | commit_and_tag long_common_tail file.c && |
| 68 | |
| 69 | git checkout initial && |
| 70 | cat "$dir/hello.c" "$dir/dummy.c" >file.c && |
| 71 | commit_and_tag hello_dummy file.c && |
| 72 | |
| 73 | # overlap function context of 1st change and -u context of 2nd change |
| 74 | grep -v "delete me from hello" <"$dir/hello.c" >file.c && |
| 75 | sed "2a\\ |
| 76 | extra line" <"$dir/dummy.c" >>file.c && |
| 77 | commit_and_tag changed_hello_dummy file.c && |
| 78 | |
| 79 | git checkout initial && |
| 80 | grep -v "delete me from hello" <file.c >file.c.new && |
| 81 | mv file.c.new file.c && |
| 82 | cat "$dir/appended1.c" >>file.c && |
| 83 | commit_and_tag changed_hello_appended file.c |
| 84 | ' |
| 85 | |
| 86 | check_diff changed_hello 'changed function' |
| 87 | |
| 88 | test_expect_success ' context includes comment' ' |
| 89 | test_grep "^ .*Hello comment" changed_hello.diff |
| 90 | ' |
| 91 | |
| 92 | test_expect_success ' context includes begin' ' |
| 93 | test_grep "^ .*Begin of hello" changed_hello.diff |
| 94 | ' |
| 95 | |
| 96 | test_expect_success ' context includes end' ' |
| 97 | test_grep "^ .*End of hello" changed_hello.diff |
| 98 | ' |
| 99 | |
| 100 | test_expect_success ' context does not include other functions' ' |
| 101 | test $(grep -c "^[ +-].*Begin" changed_hello.diff) -le 1 |
| 102 | ' |
| 103 | |
| 104 | test_expect_success ' context does not include preceding empty lines' ' |
| 105 | test "$(first_context_line <changed_hello.diff)" != " " |
| 106 | ' |
| 107 | |
| 108 | test_expect_success ' context does not include trailing empty lines' ' |
| 109 | test "$(last_context_line <changed_hello.diff)" != " " |
| 110 | ' |
| 111 | |
| 112 | check_diff changed_includes 'changed includes' |
| 113 | |
| 114 | test_expect_success ' context includes begin' ' |
| 115 | test_grep "^ .*Begin.h" changed_includes.diff |
| 116 | ' |
| 117 | |
| 118 | test_expect_success ' context includes end' ' |
| 119 | test_grep "^ .*End.h" changed_includes.diff |
| 120 | ' |
| 121 | |
| 122 | test_expect_success ' context does not include other functions' ' |
| 123 | test $(grep -c "^[ +-].*Begin" changed_includes.diff) -le 1 |
| 124 | ' |
| 125 | |
| 126 | test_expect_success ' context does not include trailing empty lines' ' |
| 127 | test "$(last_context_line <changed_includes.diff)" != " " |
| 128 | ' |
| 129 | |
| 130 | check_diff appended 'appended function' |
| 131 | |
| 132 | test_expect_success ' context includes begin' ' |
| 133 | test_grep "^[+].*Begin of first part" appended.diff |
| 134 | ' |
| 135 | |
| 136 | test_expect_success ' context includes end' ' |
| 137 | test_grep "^[+].*End of first part" appended.diff |
| 138 | ' |
| 139 | |
| 140 | test_expect_success ' context does not include other functions' ' |
| 141 | test $(grep -c "^[ +-].*Begin" appended.diff) -le 1 |
| 142 | ' |
| 143 | |
| 144 | check_diff extended 'appended function part' |
| 145 | |
| 146 | test_expect_success ' context includes begin' ' |
| 147 | test_grep "^ .*Begin of first part" extended.diff |
| 148 | ' |
| 149 | |
| 150 | test_expect_success ' context includes end' ' |
| 151 | test_grep "^[+].*End of second part" extended.diff |
| 152 | ' |
| 153 | |
| 154 | test_expect_success ' context does not include other functions' ' |
| 155 | test $(grep -c "^[ +-].*Begin" extended.diff) -le 2 |
| 156 | ' |
| 157 | |
| 158 | test_expect_success ' context does not include preceding empty lines' ' |
| 159 | test "$(first_context_line <extended.diff)" != " " |
| 160 | ' |
| 161 | |
| 162 | check_diff long_common_tail 'change with long common tail and no context' -U0 |
| 163 | |
| 164 | test_expect_success ' context includes begin' ' |
| 165 | test_grep "^ .*Begin of first part" long_common_tail.diff |
| 166 | ' |
| 167 | |
| 168 | test_expect_success ' context includes end' ' |
| 169 | test_grep "^ .*End of second part" long_common_tail.diff |
| 170 | ' |
| 171 | |
| 172 | test_expect_success ' context does not include other functions' ' |
| 173 | test $(grep -c "^[ +-].*Begin" long_common_tail.diff) -le 2 |
| 174 | ' |
| 175 | |
| 176 | test_expect_success ' context does not include preceding empty lines' ' |
| 177 | test "$(first_context_line <long_common_tail.diff)" != " " |
| 178 | ' |
| 179 | |
| 180 | check_diff changed_hello_appended 'changed function plus appended function' |
| 181 | |
| 182 | test_expect_success ' context includes begin' ' |
| 183 | test_grep "^ .*Begin of hello" changed_hello_appended.diff && |
| 184 | test_grep "^[+].*Begin of first part" changed_hello_appended.diff |
| 185 | ' |
| 186 | |
| 187 | test_expect_success ' context includes end' ' |
| 188 | test_grep "^ .*End of hello" changed_hello_appended.diff && |
| 189 | test_grep "^[+].*End of first part" changed_hello_appended.diff |
| 190 | ' |
| 191 | |
| 192 | test_expect_success ' context does not include other functions' ' |
| 193 | test $(grep -c "^[ +-].*Begin" changed_hello_appended.diff) -le 2 |
| 194 | ' |
| 195 | |
| 196 | check_diff changed_hello_dummy 'changed two consecutive functions' |
| 197 | |
| 198 | test_expect_success ' context includes begin' ' |
| 199 | test_grep "^ .*Begin of hello" changed_hello_dummy.diff && |
| 200 | test_grep "^ .*Begin of dummy" changed_hello_dummy.diff |
| 201 | ' |
| 202 | |
| 203 | test_expect_success ' context includes end' ' |
| 204 | test_grep "^ .*End of hello" changed_hello_dummy.diff && |
| 205 | test_grep "^ .*End of dummy" changed_hello_dummy.diff |
| 206 | ' |
| 207 | |
| 208 | test_expect_success ' overlapping hunks are merged' ' |
| 209 | test $(grep -c "^@@" changed_hello_dummy.diff) -eq 1 |
| 210 | ' |
| 211 | |
| 212 | test_done |