| 1 | #!/bin/sh |
| 2 | # |
| 3 | # Copyright (c) 2023 Eric Biederman |
| 4 | # |
| 5 | |
| 6 | test_description='Test how well compatObjectFormat works' |
| 7 | |
| 8 | . ./test-lib.sh |
| 9 | . "$TEST_DIRECTORY"/lib-gpg.sh |
| 10 | |
| 11 | if ! test_have_prereq RUST |
| 12 | then |
| 13 | skip_all='interoperability requires a Git built with Rust' |
| 14 | test_done |
| 15 | fi |
| 16 | |
| 17 | # All of the follow variables must be defined in the environment: |
| 18 | # GIT_AUTHOR_NAME |
| 19 | # GIT_AUTHOR_EMAIL |
| 20 | # GIT_AUTHOR_DATE |
| 21 | # GIT_COMMITTER_NAME |
| 22 | # GIT_COMMITTER_EMAIL |
| 23 | # GIT_COMMITTER_DATE |
| 24 | # |
| 25 | # The test relies on these variables being set so that the two |
| 26 | # different commits in two different repositories encoded with two |
| 27 | # different hash functions result in the same content in the commits. |
| 28 | # This means that when the commit is translated between hash functions |
| 29 | # the commit is identical to the commit in the other repository. |
| 30 | # |
| 31 | # Similarly this test relies on: |
| 32 | # gpg --faked-system-time '20230918T154812! |
| 33 | # freezing the system time from gpg perspective so that two different |
| 34 | # runs of gpg applied to the same data result in identical signatures. |
| 35 | # |
| 36 | |
| 37 | compat_hash () { |
| 38 | case "$1" in |
| 39 | "sha1") |
| 40 | echo "sha256" |
| 41 | ;; |
| 42 | "sha256") |
| 43 | echo "sha1" |
| 44 | ;; |
| 45 | esac |
| 46 | } |
| 47 | |
| 48 | hello_oid () { |
| 49 | case "$1" in |
| 50 | "sha1") |
| 51 | echo "$hello_sha1_oid" |
| 52 | ;; |
| 53 | "sha256") |
| 54 | echo "$hello_sha256_oid" |
| 55 | ;; |
| 56 | esac |
| 57 | } |
| 58 | |
| 59 | tree_oid () { |
| 60 | case "$1" in |
| 61 | "sha1") |
| 62 | echo "$tree_sha1_oid" |
| 63 | ;; |
| 64 | "sha256") |
| 65 | echo "$tree_sha256_oid" |
| 66 | ;; |
| 67 | esac |
| 68 | } |
| 69 | |
| 70 | commit_oid () { |
| 71 | case "$1" in |
| 72 | "sha1") |
| 73 | echo "$commit_sha1_oid" |
| 74 | ;; |
| 75 | "sha256") |
| 76 | echo "$commit_sha256_oid" |
| 77 | ;; |
| 78 | esac |
| 79 | } |
| 80 | |
| 81 | commit2_oid () { |
| 82 | case "$1" in |
| 83 | "sha1") |
| 84 | echo "$commit2_sha1_oid" |
| 85 | ;; |
| 86 | "sha256") |
| 87 | echo "$commit2_sha256_oid" |
| 88 | ;; |
| 89 | esac |
| 90 | } |
| 91 | |
| 92 | del_sigcommit () { |
| 93 | local delete="$1" |
| 94 | |
| 95 | if test "$delete" = "sha256" ; then |
| 96 | local pattern="gpgsig-sha256" |
| 97 | else |
| 98 | local pattern="gpgsig" |
| 99 | fi |
| 100 | test-tool delete-gpgsig "$pattern" |
| 101 | } |
| 102 | |
| 103 | del_sigtag () { |
| 104 | local storage="$1" |
| 105 | local delete="$2" |
| 106 | |
| 107 | if test "$storage" = "$delete" ; then |
| 108 | local pattern="trailer" |
| 109 | elif test "$storage" = "sha256" ; then |
| 110 | local pattern="gpgsig" |
| 111 | else |
| 112 | local pattern="gpgsig-sha256" |
| 113 | fi |
| 114 | test-tool delete-gpgsig "$pattern" |
| 115 | } |
| 116 | |
| 117 | base=$(pwd) |
| 118 | for hash in sha1 sha256 |
| 119 | do |
| 120 | cd "$base" |
| 121 | mkdir -p repo-$hash |
| 122 | cd repo-$hash |
| 123 | |
| 124 | test_expect_success "setup $hash repository" ' |
| 125 | git init --object-format=$hash && |
| 126 | git config core.repositoryformatversion 1 && |
| 127 | git config extensions.objectformat $hash && |
| 128 | git config extensions.compatobjectformat $(compat_hash $hash) && |
| 129 | git config gpg.program $TEST_DIRECTORY/t1016/gpg && |
| 130 | echo "Hello World!" >hello && |
| 131 | eval hello_${hash}_oid=$(git hash-object hello) && |
| 132 | git update-index --add hello && |
| 133 | git commit -m "Initial commit" && |
| 134 | eval commit_${hash}_oid=$(git rev-parse HEAD) && |
| 135 | eval tree_${hash}_oid=$(git rev-parse HEAD^{tree}) |
| 136 | ' |
| 137 | test_expect_success "create a $hash tagged blob" ' |
| 138 | git tag --no-sign -m "This is a tag" hellotag $(hello_oid $hash) && |
| 139 | eval hellotag_${hash}_oid=$(git rev-parse hellotag) |
| 140 | ' |
| 141 | test_expect_success "create a $hash tagged tree" ' |
| 142 | git tag --no-sign -m "This is a tag" treetag $(tree_oid $hash) && |
| 143 | eval treetag_${hash}_oid=$(git rev-parse treetag) |
| 144 | ' |
| 145 | test_expect_success "create a $hash tagged commit" ' |
| 146 | git tag --no-sign -m "This is a tag" committag $(commit_oid $hash) && |
| 147 | eval committag_${hash}_oid=$(git rev-parse committag) |
| 148 | ' |
| 149 | test_expect_success GPG2 "create a $hash signed commit" ' |
| 150 | git commit --gpg-sign --allow-empty -m "This is a signed commit" && |
| 151 | eval signedcommit_${hash}_oid=$(git rev-parse HEAD) |
| 152 | ' |
| 153 | test_expect_success GPG2 "create a $hash signed tag" ' |
| 154 | git tag -s -m "This is a signed tag" signedtag HEAD && |
| 155 | eval signedtag_${hash}_oid=$(git rev-parse signedtag) |
| 156 | ' |
| 157 | test_expect_success "create a $hash branch" ' |
| 158 | git checkout -b branch $(commit_oid $hash) && |
| 159 | echo "More more more give me more!" >more && |
| 160 | eval more_${hash}_oid=$(git hash-object more) && |
| 161 | echo "Another and another and another" >another && |
| 162 | eval another_${hash}_oid=$(git hash-object another) && |
| 163 | git update-index --add more another && |
| 164 | git commit -m "Add more files!" && |
| 165 | eval commit2_${hash}_oid=$(git rev-parse HEAD) && |
| 166 | eval tree2_${hash}_oid=$(git rev-parse HEAD^{tree}) |
| 167 | ' |
| 168 | test_expect_success GPG2 "create another $hash signed tag" ' |
| 169 | git tag -s -m "This is another signed tag" signedtag2 $(commit2_oid $hash) && |
| 170 | eval signedtag2_${hash}_oid=$(git rev-parse signedtag2) |
| 171 | ' |
| 172 | test_expect_success GPG2 "merge the $hash branches together" ' |
| 173 | git merge -S -m "merge some signed tags together" signedtag signedtag2 && |
| 174 | eval signedcommit2_${hash}_oid=$(git rev-parse HEAD) |
| 175 | ' |
| 176 | test_expect_success GPG2 "create additional $hash signed commits" ' |
| 177 | git commit --gpg-sign --allow-empty -m "This is an additional signed commit" && |
| 178 | git cat-file commit HEAD | del_sigcommit sha256 >"../${hash}_signedcommit3" && |
| 179 | git cat-file commit HEAD | del_sigcommit sha1 >"../${hash}_signedcommit4" && |
| 180 | eval signedcommit3_${hash}_oid=$(git hash-object -t commit -w ../${hash}_signedcommit3) && |
| 181 | eval signedcommit4_${hash}_oid=$(git hash-object -t commit -w ../${hash}_signedcommit4) |
| 182 | ' |
| 183 | test_expect_success GPG2 "create additional $hash signed tags" ' |
| 184 | git tag -s -m "This is an additional signed tag" signedtag34 HEAD && |
| 185 | git cat-file tag signedtag34 | del_sigtag "${hash}" sha256 >../${hash}_signedtag3 && |
| 186 | git cat-file tag signedtag34 | del_sigtag "${hash}" sha1 >../${hash}_signedtag4 && |
| 187 | eval signedtag3_${hash}_oid=$(git hash-object -t tag -w ../${hash}_signedtag3) && |
| 188 | eval signedtag4_${hash}_oid=$(git hash-object -t tag -w ../${hash}_signedtag4) |
| 189 | ' |
| 190 | done |
| 191 | cd "$base" |
| 192 | |
| 193 | compare_oids () { |
| 194 | test "$#" = 5 && { local PREREQ="$1"; shift; } || PREREQ= |
| 195 | local type="$1" |
| 196 | local name="$2" |
| 197 | local sha1_oid="$3" |
| 198 | local sha256_oid="$4" |
| 199 | |
| 200 | echo ${sha1_oid} >${name}_sha1_expected |
| 201 | echo ${sha256_oid} >${name}_sha256_expected |
| 202 | echo ${type} >${name}_type_expected |
| 203 | |
| 204 | git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} >${name}_sha1_sha256_found |
| 205 | git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} >${name}_sha256_sha1_found |
| 206 | local sha1_sha256_oid="$(cat ${name}_sha1_sha256_found)" |
| 207 | local sha256_sha1_oid="$(cat ${name}_sha256_sha1_found)" |
| 208 | |
| 209 | test_expect_success $PREREQ "Verify ${type} ${name}'s sha1 oid" ' |
| 210 | git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} >${name}_sha1 && |
| 211 | test_cmp ${name}_sha1 ${name}_sha1_expected |
| 212 | ' |
| 213 | |
| 214 | test_expect_success $PREREQ "Verify ${type} ${name}'s sha256 oid" ' |
| 215 | git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} >${name}_sha256 && |
| 216 | test_cmp ${name}_sha256 ${name}_sha256_expected |
| 217 | ' |
| 218 | |
| 219 | test_expect_success $PREREQ "Verify ${name}'s sha1 type" ' |
| 220 | git --git-dir=repo-sha1/.git cat-file -t ${sha1_oid} >${name}_type1 && |
| 221 | git --git-dir=repo-sha256/.git cat-file -t ${sha256_sha1_oid} >${name}_type2 && |
| 222 | test_cmp ${name}_type1 ${name}_type2 && |
| 223 | test_cmp ${name}_type1 ${name}_type_expected |
| 224 | ' |
| 225 | |
| 226 | test_expect_success $PREREQ "Verify ${name}'s sha256 type" ' |
| 227 | git --git-dir=repo-sha256/.git cat-file -t ${sha256_oid} >${name}_type3 && |
| 228 | git --git-dir=repo-sha1/.git cat-file -t ${sha1_sha256_oid} >${name}_type4 && |
| 229 | test_cmp ${name}_type3 ${name}_type4 && |
| 230 | test_cmp ${name}_type3 ${name}_type_expected |
| 231 | ' |
| 232 | |
| 233 | test_expect_success $PREREQ "Verify ${name}'s sha1 size" ' |
| 234 | git --git-dir=repo-sha1/.git cat-file -s ${sha1_oid} >${name}_size1 && |
| 235 | git --git-dir=repo-sha256/.git cat-file -s ${sha256_sha1_oid} >${name}_size2 && |
| 236 | test_cmp ${name}_size1 ${name}_size2 |
| 237 | ' |
| 238 | |
| 239 | test_expect_success $PREREQ "Verify ${name}'s sha256 size" ' |
| 240 | git --git-dir=repo-sha256/.git cat-file -s ${sha256_oid} >${name}_size3 && |
| 241 | git --git-dir=repo-sha1/.git cat-file -s ${sha1_sha256_oid} >${name}_size4 && |
| 242 | test_cmp ${name}_size3 ${name}_size4 |
| 243 | ' |
| 244 | |
| 245 | test_expect_success $PREREQ "Verify ${name}'s sha1 pretty content" ' |
| 246 | git --git-dir=repo-sha1/.git cat-file -p ${sha1_oid} >${name}_content1 && |
| 247 | git --git-dir=repo-sha256/.git cat-file -p ${sha256_sha1_oid} >${name}_content2 && |
| 248 | test_cmp ${name}_content1 ${name}_content2 |
| 249 | ' |
| 250 | |
| 251 | test_expect_success $PREREQ "Verify ${name}'s sha256 pretty content" ' |
| 252 | git --git-dir=repo-sha256/.git cat-file -p ${sha256_oid} >${name}_content3 && |
| 253 | git --git-dir=repo-sha1/.git cat-file -p ${sha1_sha256_oid} >${name}_content4 && |
| 254 | test_cmp ${name}_content3 ${name}_content4 |
| 255 | ' |
| 256 | |
| 257 | test_expect_success $PREREQ "Verify ${name}'s sha1 content" ' |
| 258 | git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_oid} >${name}_content5 && |
| 259 | git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_sha1_oid} >${name}_content6 && |
| 260 | test_cmp ${name}_content5 ${name}_content6 |
| 261 | ' |
| 262 | |
| 263 | test_expect_success $PREREQ "Verify ${name}'s sha256 content" ' |
| 264 | git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_oid} >${name}_content7 && |
| 265 | git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_sha256_oid} >${name}_content8 && |
| 266 | test_cmp ${name}_content7 ${name}_content8 |
| 267 | ' |
| 268 | } |
| 269 | |
| 270 | compare_oids 'blob' hello "$hello_sha1_oid" "$hello_sha256_oid" |
| 271 | compare_oids 'tree' tree "$tree_sha1_oid" "$tree_sha256_oid" |
| 272 | compare_oids 'commit' commit "$commit_sha1_oid" "$commit_sha256_oid" |
| 273 | compare_oids GPG2 'commit' signedcommit "$signedcommit_sha1_oid" "$signedcommit_sha256_oid" |
| 274 | compare_oids 'tag' hellotag "$hellotag_sha1_oid" "$hellotag_sha256_oid" |
| 275 | compare_oids 'tag' treetag "$treetag_sha1_oid" "$treetag_sha256_oid" |
| 276 | compare_oids 'tag' committag "$committag_sha1_oid" "$committag_sha256_oid" |
| 277 | compare_oids GPG2 'tag' signedtag "$signedtag_sha1_oid" "$signedtag_sha256_oid" |
| 278 | |
| 279 | compare_oids 'blob' more "$more_sha1_oid" "$more_sha256_oid" |
| 280 | compare_oids 'blob' another "$another_sha1_oid" "$another_sha256_oid" |
| 281 | compare_oids 'tree' tree2 "$tree2_sha1_oid" "$tree2_sha256_oid" |
| 282 | compare_oids 'commit' commit2 "$commit2_sha1_oid" "$commit2_sha256_oid" |
| 283 | compare_oids GPG2 'tag' signedtag2 "$signedtag2_sha1_oid" "$signedtag2_sha256_oid" |
| 284 | compare_oids GPG2 'commit' signedcommit2 "$signedcommit2_sha1_oid" "$signedcommit2_sha256_oid" |
| 285 | compare_oids GPG2 'commit' signedcommit3 "$signedcommit3_sha1_oid" "$signedcommit3_sha256_oid" |
| 286 | compare_oids GPG2 'commit' signedcommit4 "$signedcommit4_sha1_oid" "$signedcommit4_sha256_oid" |
| 287 | compare_oids GPG2 'tag' signedtag3 "$signedtag3_sha1_oid" "$signedtag3_sha256_oid" |
| 288 | compare_oids GPG2 'tag' signedtag4 "$signedtag4_sha1_oid" "$signedtag4_sha256_oid" |
| 289 | |
| 290 | test_done |