| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='git patch-id' |
| 4 | |
| 5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
| 6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
| 7 | |
| 8 | . ./test-lib.sh |
| 9 | |
| 10 | test_expect_success 'setup' ' |
| 11 | str="ab cd ef gh ij kl mn op" && |
| 12 | test_write_lines $str >foo && |
| 13 | test_write_lines $str >bar && |
| 14 | git add foo bar && |
| 15 | git commit -a -m initial && |
| 16 | test_write_lines $str b >foo && |
| 17 | test_write_lines $str b >bar && |
| 18 | git commit -a -m first && |
| 19 | git checkout -b same main && |
| 20 | git commit --amend -m same-msg && |
| 21 | git checkout -b notsame main && |
| 22 | echo c >foo && |
| 23 | echo c >bar && |
| 24 | git commit --amend -a -m notsame-msg && |
| 25 | git checkout -b with_space main~ && |
| 26 | cat >foo <<-\EOF && |
| 27 | a b |
| 28 | c d |
| 29 | e f |
| 30 | g h |
| 31 | i j |
| 32 | k l |
| 33 | m n |
| 34 | op |
| 35 | EOF |
| 36 | cp foo bar && |
| 37 | git add foo bar && |
| 38 | git commit --amend -m "with spaces" && |
| 39 | test_write_lines bar foo >bar-then-foo && |
| 40 | test_write_lines foo bar >foo-then-bar |
| 41 | |
| 42 | ' |
| 43 | |
| 44 | test_expect_success 'patch-id output is well-formed' ' |
| 45 | git log -p -1 >log.output && |
| 46 | git patch-id <log.output >output && |
| 47 | test_grep "^$OID_REGEX $(git rev-parse HEAD)$" output |
| 48 | ' |
| 49 | |
| 50 | #calculate patch id. Make sure output is not empty. |
| 51 | calc_patch_id () { |
| 52 | patch_name="$1" |
| 53 | shift |
| 54 | git patch-id "$@" >patch-id.output && |
| 55 | sed "s/ .*//" patch-id.output >patch-id_"$patch_name" && |
| 56 | test_line_count -eq 1 patch-id_"$patch_name" |
| 57 | } |
| 58 | |
| 59 | get_top_diff () { |
| 60 | git log -p -1 "$@" -O bar-then-foo --full-index -- |
| 61 | } |
| 62 | |
| 63 | get_patch_id () { |
| 64 | get_top_diff "$1" >top-diff.output && |
| 65 | calc_patch_id <top-diff.output "$@" |
| 66 | } |
| 67 | |
| 68 | test_expect_success 'patch-id detects equality' ' |
| 69 | get_patch_id main && |
| 70 | get_patch_id same && |
| 71 | test_cmp patch-id_main patch-id_same |
| 72 | ' |
| 73 | |
| 74 | test_expect_success 'patch-id detects inequality' ' |
| 75 | get_patch_id main && |
| 76 | get_patch_id notsame && |
| 77 | ! test_cmp patch-id_main patch-id_notsame |
| 78 | ' |
| 79 | test_expect_success 'patch-id detects equality binary' ' |
| 80 | cat >.gitattributes <<-\EOF && |
| 81 | foo binary |
| 82 | bar binary |
| 83 | EOF |
| 84 | get_patch_id main && |
| 85 | get_patch_id same && |
| 86 | git log -p -1 --binary main >top-diff.output && |
| 87 | calc_patch_id <top-diff.output main_binpatch && |
| 88 | git log -p -1 --binary same >top-diff.output && |
| 89 | calc_patch_id <top-diff.output same_binpatch && |
| 90 | test_cmp patch-id_main patch-id_main_binpatch && |
| 91 | test_cmp patch-id_same patch-id_same_binpatch && |
| 92 | test_cmp patch-id_main patch-id_same && |
| 93 | test_when_finished "rm .gitattributes" |
| 94 | ' |
| 95 | |
| 96 | test_expect_success 'patch-id detects inequality binary' ' |
| 97 | cat >.gitattributes <<-\EOF && |
| 98 | foo binary |
| 99 | bar binary |
| 100 | EOF |
| 101 | get_patch_id main && |
| 102 | get_patch_id notsame && |
| 103 | ! test_cmp patch-id_main patch-id_notsame && |
| 104 | test_when_finished "rm .gitattributes" |
| 105 | ' |
| 106 | |
| 107 | test_expect_success 'patch-id supports git-format-patch output' ' |
| 108 | get_patch_id main && |
| 109 | git checkout same && |
| 110 | git format-patch -1 --stdout >format-patch.output && |
| 111 | calc_patch_id same <format-patch.output && |
| 112 | test_cmp patch-id_main patch-id_same && |
| 113 | set $(git patch-id <format-patch.output) && |
| 114 | test "$2" = $(git rev-parse HEAD) |
| 115 | ' |
| 116 | |
| 117 | test_expect_success 'whitespace is irrelevant in footer' ' |
| 118 | get_patch_id main && |
| 119 | git checkout same && |
| 120 | git format-patch -1 --stdout >format-patch.output && |
| 121 | sed "s/ \$//" format-patch.output | calc_patch_id same && |
| 122 | test_cmp patch-id_main patch-id_same |
| 123 | ' |
| 124 | |
| 125 | cmp_patch_id () { |
| 126 | if |
| 127 | test "$1" = "relevant" |
| 128 | then |
| 129 | ! test_cmp patch-id_"$2" patch-id_"$3" |
| 130 | else |
| 131 | test_cmp patch-id_"$2" patch-id_"$3" |
| 132 | fi |
| 133 | } |
| 134 | |
| 135 | test_patch_id_file_order () { |
| 136 | relevant="$1" |
| 137 | shift |
| 138 | name="order-${1}-$relevant" |
| 139 | shift |
| 140 | get_top_diff "main" >top-diff.output && |
| 141 | calc_patch_id <top-diff.output "$name" "$@" && |
| 142 | git checkout same && |
| 143 | git format-patch -1 --stdout -O foo-then-bar >format-patch.output && |
| 144 | calc_patch_id <format-patch.output "ordered-$name" "$@" && |
| 145 | cmp_patch_id $relevant "$name" "ordered-$name" |
| 146 | } |
| 147 | |
| 148 | test_patch_id_whitespace () { |
| 149 | relevant="$1" |
| 150 | shift |
| 151 | name="ws-${1}-$relevant" |
| 152 | shift |
| 153 | get_top_diff "main~" >top-diff.output && |
| 154 | calc_patch_id <top-diff.output "$name" "$@" && |
| 155 | get_top_diff "with_space" >top-diff.output && |
| 156 | calc_patch_id <top-diff.output "ws-$name" "$@" && |
| 157 | cmp_patch_id $relevant "$name" "ws-$name" |
| 158 | } |
| 159 | |
| 160 | |
| 161 | # combined test for options: add more tests here to make them |
| 162 | # run with all options |
| 163 | test_patch_id () { |
| 164 | test_patch_id_file_order "$@" |
| 165 | } |
| 166 | |
| 167 | # small tests with detailed diagnostic for basic options. |
| 168 | test_expect_success 'file order is irrelevant with --stable' ' |
| 169 | test_patch_id_file_order irrelevant --stable --stable |
| 170 | ' |
| 171 | |
| 172 | test_expect_success 'file order is relevant with --unstable' ' |
| 173 | test_patch_id_file_order relevant --unstable --unstable |
| 174 | ' |
| 175 | |
| 176 | test_expect_success 'whitespace is relevant with --verbatim' ' |
| 177 | test_patch_id_whitespace relevant --verbatim --verbatim |
| 178 | ' |
| 179 | |
| 180 | test_expect_success 'whitespace is irrelevant without --verbatim' ' |
| 181 | test_patch_id_whitespace irrelevant --stable --stable |
| 182 | ' |
| 183 | |
| 184 | #Now test various option combinations. |
| 185 | test_expect_success 'default is unstable' ' |
| 186 | test_patch_id relevant default |
| 187 | ' |
| 188 | |
| 189 | test_expect_success 'patchid.stable = true is stable' ' |
| 190 | test_config patchid.stable true && |
| 191 | test_patch_id irrelevant patchid.stable=true |
| 192 | ' |
| 193 | |
| 194 | test_expect_success 'patchid.stable = false is unstable' ' |
| 195 | test_config patchid.stable false && |
| 196 | test_patch_id relevant patchid.stable=false |
| 197 | ' |
| 198 | |
| 199 | test_expect_success 'patchid.verbatim = true is correct and stable' ' |
| 200 | test_config patchid.verbatim true && |
| 201 | test_patch_id_whitespace relevant patchid.verbatim=true && |
| 202 | test_patch_id irrelevant patchid.verbatim=true |
| 203 | ' |
| 204 | |
| 205 | test_expect_success 'patchid.verbatim = false is unstable' ' |
| 206 | test_config patchid.verbatim false && |
| 207 | test_patch_id relevant patchid.verbatim=false |
| 208 | ' |
| 209 | |
| 210 | test_expect_success '--unstable overrides patchid.stable = true' ' |
| 211 | test_config patchid.stable true && |
| 212 | test_patch_id relevant patchid.stable=true--unstable --unstable |
| 213 | ' |
| 214 | |
| 215 | test_expect_success '--stable overrides patchid.stable = false' ' |
| 216 | test_config patchid.stable false && |
| 217 | test_patch_id irrelevant patchid.stable=false--stable --stable |
| 218 | ' |
| 219 | |
| 220 | test_expect_success '--verbatim overrides patchid.stable = false' ' |
| 221 | test_config patchid.stable false && |
| 222 | test_patch_id_whitespace relevant stable=false--verbatim --verbatim |
| 223 | ' |
| 224 | |
| 225 | test_expect_success 'patch-id supports git-format-patch MIME output' ' |
| 226 | get_patch_id main && |
| 227 | git checkout same && |
| 228 | git format-patch -1 --attach --stdout >format-patch.output && |
| 229 | calc_patch_id <format-patch.output same && |
| 230 | test_cmp patch-id_main patch-id_same |
| 231 | ' |
| 232 | |
| 233 | test_expect_success 'patch-id respects config from subdir' ' |
| 234 | test_config patchid.stable true && |
| 235 | mkdir subdir && |
| 236 | |
| 237 | # copy these because test_patch_id() looks for them in |
| 238 | # the current directory |
| 239 | cp bar-then-foo foo-then-bar subdir && |
| 240 | |
| 241 | ( |
| 242 | cd subdir && |
| 243 | test_patch_id irrelevant patchid.stable=true |
| 244 | ) |
| 245 | ' |
| 246 | |
| 247 | test_expect_success 'patch-id handles no-nl-at-eof markers' ' |
| 248 | cat >nonl <<-\EOF && |
| 249 | diff --git i/a w/a |
| 250 | index e69de29..2e65efe 100644 |
| 251 | --- i/a |
| 252 | +++ w/a |
| 253 | @@ -0,0 +1 @@ |
| 254 | +a |
| 255 | \ No newline at end of file |
| 256 | diff --git i/b w/b |
| 257 | index e69de29..6178079 100644 |
| 258 | --- i/b |
| 259 | +++ w/b |
| 260 | @@ -0,0 +1 @@ |
| 261 | +b |
| 262 | EOF |
| 263 | cat >withnl <<-\EOF && |
| 264 | diff --git i/a w/a |
| 265 | index e69de29..7898192 100644 |
| 266 | --- i/a |
| 267 | +++ w/a |
| 268 | @@ -0,0 +1 @@ |
| 269 | +a |
| 270 | diff --git i/b w/b |
| 271 | index e69de29..6178079 100644 |
| 272 | --- i/b |
| 273 | +++ w/b |
| 274 | @@ -0,0 +1 @@ |
| 275 | +b |
| 276 | EOF |
| 277 | calc_patch_id nonl <nonl && |
| 278 | calc_patch_id withnl <withnl && |
| 279 | test_cmp patch-id_nonl patch-id_withnl && |
| 280 | calc_patch_id nonl-inc-ws --verbatim <nonl && |
| 281 | calc_patch_id withnl-inc-ws --verbatim <withnl && |
| 282 | ! test_cmp patch-id_nonl-inc-ws patch-id_withnl-inc-ws |
| 283 | ' |
| 284 | |
| 285 | test_expect_success 'patch-id handles diffs with one line of before/after' ' |
| 286 | cat >diffu1 <<-\EOF && |
| 287 | diff --git a/bar b/bar |
| 288 | index bdaf90f..31051f6 100644 |
| 289 | --- a/bar |
| 290 | +++ b/bar |
| 291 | @@ -2 +2,2 @@ |
| 292 | b |
| 293 | +c |
| 294 | diff --git a/car b/car |
| 295 | index 00750ed..2ae5e34 100644 |
| 296 | --- a/car |
| 297 | +++ b/car |
| 298 | @@ -1 +1,2 @@ |
| 299 | 3 |
| 300 | +d |
| 301 | diff --git a/foo b/foo |
| 302 | index e439850..7146eb8 100644 |
| 303 | --- a/foo |
| 304 | +++ b/foo |
| 305 | @@ -2 +2,2 @@ |
| 306 | a |
| 307 | +e |
| 308 | EOF |
| 309 | calc_patch_id diffu1 <diffu1 && |
| 310 | test_config patchid.stable true && |
| 311 | calc_patch_id diffu1stable <diffu1 |
| 312 | ' |
| 313 | |
| 314 | test_expect_failure 'patch-id computes same ID with different object hashes' ' |
| 315 | test_when_finished "rm -rf repo-sha1 repo-sha256" && |
| 316 | |
| 317 | cat >diff <<-\EOF && |
| 318 | diff --git a/bar b/bar |
| 319 | index bdaf90f..31051f6 100644 |
| 320 | --- a/bar |
| 321 | +++ b/bar |
| 322 | @@ -2 +2,2 @@ |
| 323 | b |
| 324 | +c |
| 325 | EOF |
| 326 | |
| 327 | git init --object-format=sha1 repo-sha1 && |
| 328 | git -C repo-sha1 patch-id <diff >patch-id-sha1 && |
| 329 | git init --object-format=sha256 repo-sha256 && |
| 330 | git -C repo-sha256 patch-id <diff >patch-id-sha256 && |
| 331 | test_cmp patch-id-sha1 patch-id-sha256 |
| 332 | ' |
| 333 | |
| 334 | test_expect_success 'patch-id without repository' ' |
| 335 | cat >diff <<-\EOF && |
| 336 | diff --git a/bar b/bar |
| 337 | index bdaf90f..31051f6 100644 |
| 338 | --- a/bar |
| 339 | +++ b/bar |
| 340 | @@ -2 +2,2 @@ |
| 341 | b |
| 342 | +c |
| 343 | EOF |
| 344 | nongit git patch-id <diff |
| 345 | ' |
| 346 | |
| 347 | test_done |