| #!/bin/sh | |
| test_description='git patch-id' | |
| GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main | |
| export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | |
| . ./test-lib.sh | |
| test_expect_success 'setup' ' | |
| str="ab cd ef gh ij kl mn op" && | |
| test_write_lines $str >foo && | |
| test_write_lines $str >bar && | |
| git add foo bar && | |
| git commit -a -m initial && | |
| test_write_lines $str b >foo && | |
| test_write_lines $str b >bar && | |
| git commit -a -m first && | |
| git checkout -b same main && | |
| git commit --amend -m same-msg && | |
| git checkout -b notsame main && | |
| echo c >foo && | |
| echo c >bar && | |
| git commit --amend -a -m notsame-msg && | |
| git checkout -b with_space main~ && | |
| cat >foo <<-\EOF && | |
| a b | |
| c d | |
| e f | |
| g h | |
| i j | |
| k l | |
| m n | |
| op | |
| EOF | |
| cp foo bar && | |
| git add foo bar && | |
| git commit --amend -m "with spaces" && | |
| test_write_lines bar foo >bar-then-foo && | |
| test_write_lines foo bar >foo-then-bar | |
| ' | |
| test_expect_success 'patch-id output is well-formed' ' | |
| git log -p -1 >log.output && | |
| git patch-id <log.output >output && | |
| test_grep "^$OID_REGEX $(git rev-parse HEAD)$" output | |
| ' | |
| #calculate patch id. Make sure output is not empty. | |
| calc_patch_id () { | |
| patch_name="$1" | |
| shift | |
| git patch-id "$@" >patch-id.output && | |
| sed "s/ .*//" patch-id.output >patch-id_"$patch_name" && | |
| test_line_count -eq 1 patch-id_"$patch_name" | |
| } | |
| get_top_diff () { | |
| git log -p -1 "$@" -O bar-then-foo --full-index -- | |
| } | |
| get_patch_id () { | |
| get_top_diff "$1" >top-diff.output && | |
| calc_patch_id <top-diff.output "$@" | |
| } | |
| test_expect_success 'patch-id detects equality' ' | |
| get_patch_id main && | |
| get_patch_id same && | |
| test_cmp patch-id_main patch-id_same | |
| ' | |
| test_expect_success 'patch-id detects inequality' ' | |
| get_patch_id main && | |
| get_patch_id notsame && | |
| ! test_cmp patch-id_main patch-id_notsame | |
| ' | |
| test_expect_success 'patch-id detects equality binary' ' | |
| cat >.gitattributes <<-\EOF && | |
| foo binary | |
| bar binary | |
| EOF | |
| get_patch_id main && | |
| get_patch_id same && | |
| git log -p -1 --binary main >top-diff.output && | |
| calc_patch_id <top-diff.output main_binpatch && | |
| git log -p -1 --binary same >top-diff.output && | |
| calc_patch_id <top-diff.output same_binpatch && | |
| test_cmp patch-id_main patch-id_main_binpatch && | |
| test_cmp patch-id_same patch-id_same_binpatch && | |
| test_cmp patch-id_main patch-id_same && | |
| test_when_finished "rm .gitattributes" | |
| ' | |
| test_expect_success 'patch-id detects inequality binary' ' | |
| cat >.gitattributes <<-\EOF && | |
| foo binary | |
| bar binary | |
| EOF | |
| get_patch_id main && | |
| get_patch_id notsame && | |
| ! test_cmp patch-id_main patch-id_notsame && | |
| test_when_finished "rm .gitattributes" | |
| ' | |
| test_expect_success 'patch-id supports git-format-patch output' ' | |
| get_patch_id main && | |
| git checkout same && | |
| git format-patch -1 --stdout >format-patch.output && | |
| calc_patch_id same <format-patch.output && | |
| test_cmp patch-id_main patch-id_same && | |
| set $(git patch-id <format-patch.output) && | |
| test "$2" = $(git rev-parse HEAD) | |
| ' | |
| test_expect_success 'whitespace is irrelevant in footer' ' | |
| get_patch_id main && | |
| git checkout same && | |
| git format-patch -1 --stdout >format-patch.output && | |
| sed "s/ \$//" format-patch.output | calc_patch_id same && | |
| test_cmp patch-id_main patch-id_same | |
| ' | |
| cmp_patch_id () { | |
| if | |
| test "$1" = "relevant" | |
| then | |
| ! test_cmp patch-id_"$2" patch-id_"$3" | |
| else | |
| test_cmp patch-id_"$2" patch-id_"$3" | |
| fi | |
| } | |
| test_patch_id_file_order () { | |
| relevant="$1" | |
| shift | |
| name="order-${1}-$relevant" | |
| shift | |
| get_top_diff "main" >top-diff.output && | |
| calc_patch_id <top-diff.output "$name" "$@" && | |
| git checkout same && | |
| git format-patch -1 --stdout -O foo-then-bar >format-patch.output && | |
| calc_patch_id <format-patch.output "ordered-$name" "$@" && | |
| cmp_patch_id $relevant "$name" "ordered-$name" | |
| } | |
| test_patch_id_whitespace () { | |
| relevant="$1" | |
| shift | |
| name="ws-${1}-$relevant" | |
| shift | |
| get_top_diff "main~" >top-diff.output && | |
| calc_patch_id <top-diff.output "$name" "$@" && | |
| get_top_diff "with_space" >top-diff.output && | |
| calc_patch_id <top-diff.output "ws-$name" "$@" && | |
| cmp_patch_id $relevant "$name" "ws-$name" | |
| } | |
| # combined test for options: add more tests here to make them | |
| # run with all options | |
| test_patch_id () { | |
| test_patch_id_file_order "$@" | |
| } | |
| # small tests with detailed diagnostic for basic options. | |
| test_expect_success 'file order is irrelevant with --stable' ' | |
| test_patch_id_file_order irrelevant --stable --stable | |
| ' | |
| test_expect_success 'file order is relevant with --unstable' ' | |
| test_patch_id_file_order relevant --unstable --unstable | |
| ' | |
| test_expect_success 'whitespace is relevant with --verbatim' ' | |
| test_patch_id_whitespace relevant --verbatim --verbatim | |
| ' | |
| test_expect_success 'whitespace is irrelevant without --verbatim' ' | |
| test_patch_id_whitespace irrelevant --stable --stable | |
| ' | |
| #Now test various option combinations. | |
| test_expect_success 'default is unstable' ' | |
| test_patch_id relevant default | |
| ' | |
| test_expect_success 'patchid.stable = true is stable' ' | |
| test_config patchid.stable true && | |
| test_patch_id irrelevant patchid.stable=true | |
| ' | |
| test_expect_success 'patchid.stable = false is unstable' ' | |
| test_config patchid.stable false && | |
| test_patch_id relevant patchid.stable=false | |
| ' | |
| test_expect_success 'patchid.verbatim = true is correct and stable' ' | |
| test_config patchid.verbatim true && | |
| test_patch_id_whitespace relevant patchid.verbatim=true && | |
| test_patch_id irrelevant patchid.verbatim=true | |
| ' | |
| test_expect_success 'patchid.verbatim = false is unstable' ' | |
| test_config patchid.verbatim false && | |
| test_patch_id relevant patchid.verbatim=false | |
| ' | |
| test_expect_success '--unstable overrides patchid.stable = true' ' | |
| test_config patchid.stable true && | |
| test_patch_id relevant patchid.stable=true--unstable --unstable | |
| ' | |
| test_expect_success '--stable overrides patchid.stable = false' ' | |
| test_config patchid.stable false && | |
| test_patch_id irrelevant patchid.stable=false--stable --stable | |
| ' | |
| test_expect_success '--verbatim overrides patchid.stable = false' ' | |
| test_config patchid.stable false && | |
| test_patch_id_whitespace relevant stable=false--verbatim --verbatim | |
| ' | |
| test_expect_success 'patch-id supports git-format-patch MIME output' ' | |
| get_patch_id main && | |
| git checkout same && | |
| git format-patch -1 --attach --stdout >format-patch.output && | |
| calc_patch_id <format-patch.output same && | |
| test_cmp patch-id_main patch-id_same | |
| ' | |
| test_expect_success 'patch-id respects config from subdir' ' | |
| test_config patchid.stable true && | |
| mkdir subdir && | |
| # copy these because test_patch_id() looks for them in | |
| # the current directory | |
| cp bar-then-foo foo-then-bar subdir && | |
| ( | |
| cd subdir && | |
| test_patch_id irrelevant patchid.stable=true | |
| ) | |
| ' | |
| test_expect_success 'patch-id handles no-nl-at-eof markers' ' | |
| cat >nonl <<-\EOF && | |
| diff --git i/a w/a | |
| index e69de29..2e65efe 100644 | |
| --- i/a | |
| +++ w/a | |
| @@ -0,0 +1 @@ | |
| +a | |
| \ No newline at end of file | |
| diff --git i/b w/b | |
| index e69de29..6178079 100644 | |
| --- i/b | |
| +++ w/b | |
| @@ -0,0 +1 @@ | |
| +b | |
| EOF | |
| cat >withnl <<-\EOF && | |
| diff --git i/a w/a | |
| index e69de29..7898192 100644 | |
| --- i/a | |
| +++ w/a | |
| @@ -0,0 +1 @@ | |
| +a | |
| diff --git i/b w/b | |
| index e69de29..6178079 100644 | |
| --- i/b | |
| +++ w/b | |
| @@ -0,0 +1 @@ | |
| +b | |
| EOF | |
| calc_patch_id nonl <nonl && | |
| calc_patch_id withnl <withnl && | |
| test_cmp patch-id_nonl patch-id_withnl && | |
| calc_patch_id nonl-inc-ws --verbatim <nonl && | |
| calc_patch_id withnl-inc-ws --verbatim <withnl && | |
| ! test_cmp patch-id_nonl-inc-ws patch-id_withnl-inc-ws | |
| ' | |
| test_expect_success 'patch-id handles diffs with one line of before/after' ' | |
| cat >diffu1 <<-\EOF && | |
| diff --git a/bar b/bar | |
| index bdaf90f..31051f6 100644 | |
| --- a/bar | |
| +++ b/bar | |
| @@ -2 +2,2 @@ | |
| b | |
| +c | |
| diff --git a/car b/car | |
| index 00750ed..2ae5e34 100644 | |
| --- a/car | |
| +++ b/car | |
| @@ -1 +1,2 @@ | |
| 3 | |
| +d | |
| diff --git a/foo b/foo | |
| index e439850..7146eb8 100644 | |
| --- a/foo | |
| +++ b/foo | |
| @@ -2 +2,2 @@ | |
| a | |
| +e | |
| EOF | |
| calc_patch_id diffu1 <diffu1 && | |
| test_config patchid.stable true && | |
| calc_patch_id diffu1stable <diffu1 | |
| ' | |
| test_expect_failure 'patch-id computes same ID with different object hashes' ' | |
| test_when_finished "rm -rf repo-sha1 repo-sha256" && | |
| cat >diff <<-\EOF && | |
| diff --git a/bar b/bar | |
| index bdaf90f..31051f6 100644 | |
| --- a/bar | |
| +++ b/bar | |
| @@ -2 +2,2 @@ | |
| b | |
| +c | |
| EOF | |
| git init --object-format=sha1 repo-sha1 && | |
| git -C repo-sha1 patch-id <diff >patch-id-sha1 && | |
| git init --object-format=sha256 repo-sha256 && | |
| git -C repo-sha256 patch-id <diff >patch-id-sha256 && | |
| test_cmp patch-id-sha1 patch-id-sha256 | |
| ' | |
| test_expect_success 'patch-id without repository' ' | |
| cat >diff <<-\EOF && | |
| diff --git a/bar b/bar | |
| index bdaf90f..31051f6 100644 | |
| --- a/bar | |
| +++ b/bar | |
| @@ -2 +2,2 @@ | |
| b | |
| +c | |
| EOF | |
| nongit git patch-id <diff | |
| ' | |
| test_done |