Git fork

t6300: refactor tests to be shareable

In preparation for adding tests for the new `git refs list` command,
refactor the existing t6300 test suite to make its logic shareable.

Move the core test logic from `t6300-for-each-ref.sh` into a new
`for-each-ref-tests.sh` file. Inside this new script, replace hardcoded
calls to "git for-each-ref" with the `$git_for_each_ref` variable.

The original `t6300-for-each-ref.sh` script now becomes a simple
"driver". It is responsible for setting the default value of the
variable and then sourcing the test library.

This new structure follows the established pattern used for sharing
tests between `git-blame` and `git-annotate` and prepares the test suite
for the `refs list` tests to be added in a subsequent commit.

Mentored-by: Patrick Steinhardt <ps@pks.im>
Mentored-by: shejialuo <shejialuo@gmail.com>
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Meet Soni <meetsoni3017@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Meet Soni and committed by
Junio C Hamano
aa91c5c5 eecccfe9

+2143 -2138
+2141
t/for-each-ref-tests.sh
··· 1 + git_for_each_ref=${git_for_each_ref:-git for-each-ref} 2 + GNUPGHOME_NOT_USED=$GNUPGHOME 3 + . "$TEST_DIRECTORY"/lib-gpg.sh 4 + . "$TEST_DIRECTORY"/lib-terminal.sh 5 + 6 + # Mon Jul 3 23:18:43 2006 +0000 7 + datestamp=1151968723 8 + setdate_and_increment () { 9 + GIT_COMMITTER_DATE="$datestamp +0200" 10 + datestamp=$(expr "$datestamp" + 1) 11 + GIT_AUTHOR_DATE="$datestamp +0200" 12 + datestamp=$(expr "$datestamp" + 1) 13 + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE 14 + } 15 + 16 + test_object_file_size () { 17 + oid=$(git rev-parse "$1") 18 + path=".git/objects/$(test_oid_to_path $oid)" 19 + test_file_size "$path" 20 + } 21 + 22 + test_expect_success setup ' 23 + # setup .mailmap 24 + cat >.mailmap <<-EOF && 25 + A Thor <athor@example.com> A U Thor <author@example.com> 26 + C Mitter <cmitter@example.com> C O Mitter <committer@example.com> 27 + EOF 28 + 29 + setdate_and_increment && 30 + echo "Using $datestamp" > one && 31 + git add one && 32 + git commit -m "Initial" && 33 + git branch -M main && 34 + setdate_and_increment && 35 + git tag -a -m "Tagging at $datestamp" testtag && 36 + git update-ref refs/remotes/origin/main main && 37 + git remote add origin nowhere && 38 + git config branch.main.remote origin && 39 + git config branch.main.merge refs/heads/main && 40 + git remote add myfork elsewhere && 41 + git config remote.pushdefault myfork && 42 + git config push.default current 43 + ' 44 + 45 + test_atom () { 46 + case "$1" in 47 + head) ref=refs/heads/main ;; 48 + tag) ref=refs/tags/testtag ;; 49 + sym) ref=refs/heads/sym ;; 50 + *) ref=$1 ;; 51 + esac 52 + format=$2 53 + test_do=test_expect_${4:-success} 54 + 55 + printf '%s\n' "$3" >expected 56 + $test_do $PREREQ "basic atom: $ref $format" ' 57 + ${git_for_each_ref} --format="%($format)" "$ref" >actual && 58 + sanitize_pgp <actual >actual.clean && 59 + test_cmp expected actual.clean 60 + ' 61 + 62 + # Automatically test "contents:size" atom after testing "contents" 63 + if test "$format" = "contents" 64 + then 65 + # for commit leg, $3 is changed there 66 + expect=$(printf '%s' "$3" | wc -c) 67 + $test_do $PREREQ "basic atom: $ref contents:size" ' 68 + type=$(git cat-file -t "$ref") && 69 + case $type in 70 + tag) 71 + # We cannot use $3 as it expects sanitize_pgp to run 72 + git cat-file tag $ref >out && 73 + expect=$(tail -n +6 out | wc -c) && 74 + rm -f out ;; 75 + tree | blob) 76 + expect="" ;; 77 + commit) 78 + : "use the calculated expect" ;; 79 + *) 80 + BUG "unknown object type" ;; 81 + esac && 82 + # Leave $expect unquoted to lose possible leading whitespaces 83 + echo $expect >expected && 84 + ${git_for_each_ref} --format="%(contents:size)" "$ref" >actual && 85 + test_cmp expected actual 86 + ' 87 + fi 88 + } 89 + 90 + hexlen=$(test_oid hexsz) 91 + 92 + test_atom head refname refs/heads/main 93 + test_atom head refname: refs/heads/main 94 + test_atom head refname:short main 95 + test_atom head refname:lstrip=1 heads/main 96 + test_atom head refname:lstrip=2 main 97 + test_atom head refname:lstrip=-1 main 98 + test_atom head refname:lstrip=-2 heads/main 99 + test_atom head refname:rstrip=1 refs/heads 100 + test_atom head refname:rstrip=2 refs 101 + test_atom head refname:rstrip=-1 refs 102 + test_atom head refname:rstrip=-2 refs/heads 103 + test_atom head refname:strip=1 heads/main 104 + test_atom head refname:strip=2 main 105 + test_atom head refname:strip=-1 main 106 + test_atom head refname:strip=-2 heads/main 107 + test_atom head upstream refs/remotes/origin/main 108 + test_atom head upstream:short origin/main 109 + test_atom head upstream:lstrip=2 origin/main 110 + test_atom head upstream:lstrip=-2 origin/main 111 + test_atom head upstream:rstrip=2 refs/remotes 112 + test_atom head upstream:rstrip=-2 refs/remotes 113 + test_atom head upstream:strip=2 origin/main 114 + test_atom head upstream:strip=-2 origin/main 115 + test_atom head push refs/remotes/myfork/main 116 + test_atom head push:short myfork/main 117 + test_atom head push:lstrip=1 remotes/myfork/main 118 + test_atom head push:lstrip=-1 main 119 + test_atom head push:rstrip=1 refs/remotes/myfork 120 + test_atom head push:rstrip=-1 refs 121 + test_atom head push:strip=1 remotes/myfork/main 122 + test_atom head push:strip=-1 main 123 + test_atom head objecttype commit 124 + test_atom head objectsize $((131 + hexlen)) 125 + test_atom head objectsize:disk $(test_object_file_size refs/heads/main) 126 + test_atom head deltabase $ZERO_OID 127 + test_atom head objectname $(git rev-parse refs/heads/main) 128 + test_atom head objectname:short $(git rev-parse --short refs/heads/main) 129 + test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) 130 + test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) 131 + test_atom head tree $(git rev-parse refs/heads/main^{tree}) 132 + test_atom head tree:short $(git rev-parse --short refs/heads/main^{tree}) 133 + test_atom head tree:short=1 $(git rev-parse --short=1 refs/heads/main^{tree}) 134 + test_atom head tree:short=10 $(git rev-parse --short=10 refs/heads/main^{tree}) 135 + test_atom head parent '' 136 + test_atom head parent:short '' 137 + test_atom head parent:short=1 '' 138 + test_atom head parent:short=10 '' 139 + test_atom head numparent 0 140 + test_atom head object '' 141 + test_atom head type '' 142 + test_atom head raw "$(git cat-file commit refs/heads/main) 143 + " 144 + test_atom head '*objectname' '' 145 + test_atom head '*objecttype' '' 146 + test_atom head author 'A U Thor <author@example.com> 1151968724 +0200' 147 + test_atom head authorname 'A U Thor' 148 + test_atom head authorname:mailmap 'A Thor' 149 + test_atom head authoremail '<author@example.com>' 150 + test_atom head authoremail:trim 'author@example.com' 151 + test_atom head authoremail:localpart 'author' 152 + test_atom head authoremail:trim,localpart 'author' 153 + test_atom head authoremail:mailmap '<athor@example.com>' 154 + test_atom head authoremail:mailmap,trim 'athor@example.com' 155 + test_atom head authoremail:trim,mailmap 'athor@example.com' 156 + test_atom head authoremail:mailmap,localpart 'athor' 157 + test_atom head authoremail:localpart,mailmap 'athor' 158 + test_atom head authoremail:mailmap,trim,localpart,mailmap,trim 'athor' 159 + test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200' 160 + test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200' 161 + test_atom head committername 'C O Mitter' 162 + test_atom head committername:mailmap 'C Mitter' 163 + test_atom head committeremail '<committer@example.com>' 164 + test_atom head committeremail:trim 'committer@example.com' 165 + test_atom head committeremail:localpart 'committer' 166 + test_atom head committeremail:localpart,trim 'committer' 167 + test_atom head committeremail:mailmap '<cmitter@example.com>' 168 + test_atom head committeremail:mailmap,trim 'cmitter@example.com' 169 + test_atom head committeremail:trim,mailmap 'cmitter@example.com' 170 + test_atom head committeremail:mailmap,localpart 'cmitter' 171 + test_atom head committeremail:localpart,mailmap 'cmitter' 172 + test_atom head committeremail:trim,mailmap,trim,trim,localpart 'cmitter' 173 + test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200' 174 + test_atom head tag '' 175 + test_atom head tagger '' 176 + test_atom head taggername '' 177 + test_atom head taggeremail '' 178 + test_atom head taggeremail:trim '' 179 + test_atom head taggeremail:localpart '' 180 + test_atom head taggerdate '' 181 + test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200' 182 + test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200' 183 + test_atom head subject 'Initial' 184 + test_atom head subject:sanitize 'Initial' 185 + test_atom head contents:subject 'Initial' 186 + test_atom head body '' 187 + test_atom head contents:body '' 188 + test_atom head contents:signature '' 189 + test_atom head contents 'Initial 190 + ' 191 + test_atom head HEAD '*' 192 + 193 + test_atom tag refname refs/tags/testtag 194 + test_atom tag refname:short testtag 195 + test_atom tag upstream '' 196 + test_atom tag push '' 197 + test_atom tag objecttype tag 198 + test_atom tag objectsize $((114 + hexlen)) 199 + test_atom tag objectsize:disk $(test_object_file_size refs/tags/testtag) 200 + test_atom tag '*objectsize:disk' $(test_object_file_size refs/heads/main) 201 + test_atom tag deltabase $ZERO_OID 202 + test_atom tag '*deltabase' $ZERO_OID 203 + test_atom tag objectname $(git rev-parse refs/tags/testtag) 204 + test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag) 205 + test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) 206 + test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) 207 + test_atom tag tree '' 208 + test_atom tag tree:short '' 209 + test_atom tag tree:short=1 '' 210 + test_atom tag tree:short=10 '' 211 + test_atom tag parent '' 212 + test_atom tag parent:short '' 213 + test_atom tag parent:short=1 '' 214 + test_atom tag parent:short=10 '' 215 + test_atom tag numparent '' 216 + test_atom tag object $(git rev-parse refs/tags/testtag^0) 217 + test_atom tag type 'commit' 218 + test_atom tag '*objectname' $(git rev-parse refs/tags/testtag^{}) 219 + test_atom tag '*objecttype' 'commit' 220 + test_atom tag author '' 221 + test_atom tag authorname '' 222 + test_atom tag authorname:mailmap '' 223 + test_atom tag authoremail '' 224 + test_atom tag authoremail:trim '' 225 + test_atom tag authoremail:localpart '' 226 + test_atom tag authoremail:trim,localpart '' 227 + test_atom tag authoremail:mailmap '' 228 + test_atom tag authoremail:mailmap,trim '' 229 + test_atom tag authoremail:trim,mailmap '' 230 + test_atom tag authoremail:mailmap,localpart '' 231 + test_atom tag authoremail:localpart,mailmap '' 232 + test_atom tag authoremail:mailmap,trim,localpart,mailmap,trim '' 233 + test_atom tag authordate '' 234 + test_atom tag committer '' 235 + test_atom tag committername '' 236 + test_atom tag committername:mailmap '' 237 + test_atom tag committeremail '' 238 + test_atom tag committeremail:trim '' 239 + test_atom tag committeremail:localpart '' 240 + test_atom tag committeremail:localpart,trim '' 241 + test_atom tag committeremail:mailmap '' 242 + test_atom tag committeremail:mailmap,trim '' 243 + test_atom tag committeremail:trim,mailmap '' 244 + test_atom tag committeremail:mailmap,localpart '' 245 + test_atom tag committeremail:localpart,mailmap '' 246 + test_atom tag committeremail:trim,mailmap,trim,trim,localpart '' 247 + test_atom tag committerdate '' 248 + test_atom tag tag 'testtag' 249 + test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200' 250 + test_atom tag taggername 'C O Mitter' 251 + test_atom tag taggername:mailmap 'C Mitter' 252 + test_atom tag taggeremail '<committer@example.com>' 253 + test_atom tag taggeremail:trim 'committer@example.com' 254 + test_atom tag taggeremail:localpart 'committer' 255 + test_atom tag taggeremail:trim,localpart 'committer' 256 + test_atom tag taggeremail:mailmap '<cmitter@example.com>' 257 + test_atom tag taggeremail:mailmap,trim 'cmitter@example.com' 258 + test_atom tag taggeremail:trim,mailmap 'cmitter@example.com' 259 + test_atom tag taggeremail:mailmap,localpart 'cmitter' 260 + test_atom tag taggeremail:localpart,mailmap 'cmitter' 261 + test_atom tag taggeremail:trim,mailmap,trim,localpart,localpart 'cmitter' 262 + test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200' 263 + test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200' 264 + test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200' 265 + test_atom tag subject 'Tagging at 1151968727' 266 + test_atom tag subject:sanitize 'Tagging-at-1151968727' 267 + test_atom tag contents:subject 'Tagging at 1151968727' 268 + test_atom tag body '' 269 + test_atom tag contents:body '' 270 + test_atom tag contents:signature '' 271 + test_atom tag contents 'Tagging at 1151968727 272 + ' 273 + test_atom tag HEAD ' ' 274 + 275 + test_expect_success 'basic atom: refs/tags/testtag *raw' ' 276 + git cat-file commit refs/tags/testtag^{} >expected && 277 + ${git_for_each_ref} --format="%(*raw)" refs/tags/testtag >actual && 278 + sanitize_pgp <expected >expected.clean && 279 + echo >>expected.clean && 280 + sanitize_pgp <actual >actual.clean && 281 + test_cmp expected.clean actual.clean 282 + ' 283 + 284 + test_expect_success 'Check invalid atoms names are errors' ' 285 + test_must_fail ${git_for_each_ref} --format="%(INVALID)" refs/heads 286 + ' 287 + 288 + test_expect_success 'Check format specifiers are ignored in naming date atoms' ' 289 + ${git_for_each_ref} --format="%(authordate)" refs/heads && 290 + ${git_for_each_ref} --format="%(authordate:default) %(authordate)" refs/heads && 291 + ${git_for_each_ref} --format="%(authordate) %(authordate:default)" refs/heads && 292 + ${git_for_each_ref} --format="%(authordate:default) %(authordate:default)" refs/heads 293 + ' 294 + 295 + test_expect_success 'Check valid format specifiers for date fields' ' 296 + ${git_for_each_ref} --format="%(authordate:default)" refs/heads && 297 + ${git_for_each_ref} --format="%(authordate:relative)" refs/heads && 298 + ${git_for_each_ref} --format="%(authordate:short)" refs/heads && 299 + ${git_for_each_ref} --format="%(authordate:local)" refs/heads && 300 + ${git_for_each_ref} --format="%(authordate:iso8601)" refs/heads && 301 + ${git_for_each_ref} --format="%(authordate:rfc2822)" refs/heads 302 + ' 303 + 304 + test_expect_success 'Check invalid format specifiers are errors' ' 305 + test_must_fail ${git_for_each_ref} --format="%(authordate:INVALID)" refs/heads 306 + ' 307 + 308 + test_expect_success 'arguments to %(objectname:short=) must be positive integers' ' 309 + test_must_fail ${git_for_each_ref} --format="%(objectname:short=0)" && 310 + test_must_fail ${git_for_each_ref} --format="%(objectname:short=-1)" && 311 + test_must_fail ${git_for_each_ref} --format="%(objectname:short=foo)" 312 + ' 313 + 314 + test_bad_atom () { 315 + case "$1" in 316 + head) ref=refs/heads/main ;; 317 + tag) ref=refs/tags/testtag ;; 318 + sym) ref=refs/heads/sym ;; 319 + *) ref=$1 ;; 320 + esac 321 + format=$2 322 + test_do=test_expect_${4:-success} 323 + 324 + printf '%s\n' "$3" >expect 325 + $test_do $PREREQ "err basic atom: $ref $format" ' 326 + test_must_fail ${git_for_each_ref} \ 327 + --format="%($format)" "$ref" 2>error && 328 + test_cmp expect error 329 + ' 330 + } 331 + 332 + test_bad_atom head 'authoremail:foo' \ 333 + 'fatal: unrecognized %(authoremail) argument: foo' 334 + 335 + test_bad_atom head 'authoremail:mailmap,trim,bar' \ 336 + 'fatal: unrecognized %(authoremail) argument: bar' 337 + 338 + test_bad_atom head 'authoremail:trim,' \ 339 + 'fatal: unrecognized %(authoremail) argument: ' 340 + 341 + test_bad_atom head 'authoremail:mailmaptrim' \ 342 + 'fatal: unrecognized %(authoremail) argument: trim' 343 + 344 + test_bad_atom head 'committeremail: ' \ 345 + 'fatal: unrecognized %(committeremail) argument: ' 346 + 347 + test_bad_atom head 'committeremail: trim,foo' \ 348 + 'fatal: unrecognized %(committeremail) argument: trim,foo' 349 + 350 + test_bad_atom head 'committeremail:mailmap,localpart ' \ 351 + 'fatal: unrecognized %(committeremail) argument: ' 352 + 353 + test_bad_atom head 'committeremail:trim_localpart' \ 354 + 'fatal: unrecognized %(committeremail) argument: _localpart' 355 + 356 + test_bad_atom head 'committeremail:localpart,,,trim' \ 357 + 'fatal: unrecognized %(committeremail) argument: ,,trim' 358 + 359 + test_bad_atom tag 'taggeremail:mailmap,trim, foo ' \ 360 + 'fatal: unrecognized %(taggeremail) argument: foo ' 361 + 362 + test_bad_atom tag 'taggeremail:trim,localpart,' \ 363 + 'fatal: unrecognized %(taggeremail) argument: ' 364 + 365 + test_bad_atom tag 'taggeremail:mailmap;localpart trim' \ 366 + 'fatal: unrecognized %(taggeremail) argument: ;localpart trim' 367 + 368 + test_bad_atom tag 'taggeremail:localpart trim' \ 369 + 'fatal: unrecognized %(taggeremail) argument: trim' 370 + 371 + test_bad_atom tag 'taggeremail:mailmap,mailmap,trim,qux,localpart,trim' \ 372 + 'fatal: unrecognized %(taggeremail) argument: qux,localpart,trim' 373 + 374 + test_date () { 375 + f=$1 && 376 + committer_date=$2 && 377 + author_date=$3 && 378 + tagger_date=$4 && 379 + cat >expected <<-EOF && 380 + 'refs/heads/main' '$committer_date' '$author_date' 381 + 'refs/tags/testtag' '$tagger_date' 382 + EOF 383 + ( 384 + ${git_for_each_ref} --shell \ 385 + --format="%(refname) %(committerdate${f:+:$f}) %(authordate${f:+:$f})" \ 386 + refs/heads && 387 + ${git_for_each_ref} --shell \ 388 + --format="%(refname) %(taggerdate${f:+:$f})" \ 389 + refs/tags 390 + ) >actual && 391 + test_cmp expected actual 392 + } 393 + 394 + test_expect_success 'Check unformatted date fields output' ' 395 + test_date "" \ 396 + "Tue Jul 4 01:18:43 2006 +0200" \ 397 + "Tue Jul 4 01:18:44 2006 +0200" \ 398 + "Tue Jul 4 01:18:45 2006 +0200" 399 + ' 400 + 401 + test_expect_success 'Check format "default" formatted date fields output' ' 402 + test_date default \ 403 + "Tue Jul 4 01:18:43 2006 +0200" \ 404 + "Tue Jul 4 01:18:44 2006 +0200" \ 405 + "Tue Jul 4 01:18:45 2006 +0200" 406 + ' 407 + 408 + test_expect_success 'Check format "default-local" date fields output' ' 409 + test_date default-local "Mon Jul 3 23:18:43 2006" "Mon Jul 3 23:18:44 2006" "Mon Jul 3 23:18:45 2006" 410 + ' 411 + 412 + # Don't know how to do relative check because I can't know when this script 413 + # is going to be run and can't fake the current time to git, and hence can't 414 + # provide expected output. Instead, I'll just make sure that "relative" 415 + # doesn't exit in error 416 + test_expect_success 'Check format "relative" date fields output' ' 417 + f=relative && 418 + (${git_for_each_ref} --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && 419 + ${git_for_each_ref} --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual 420 + ' 421 + 422 + # We just check that this is the same as "relative" for now. 423 + test_expect_success 'Check format "relative-local" date fields output' ' 424 + test_date relative-local \ 425 + "$(${git_for_each_ref} --format="%(committerdate:relative)" refs/heads)" \ 426 + "$(${git_for_each_ref} --format="%(authordate:relative)" refs/heads)" \ 427 + "$(${git_for_each_ref} --format="%(taggerdate:relative)" refs/tags)" 428 + ' 429 + 430 + test_expect_success 'Check format "short" date fields output' ' 431 + test_date short 2006-07-04 2006-07-04 2006-07-04 432 + ' 433 + 434 + test_expect_success 'Check format "short-local" date fields output' ' 435 + test_date short-local 2006-07-03 2006-07-03 2006-07-03 436 + ' 437 + 438 + test_expect_success 'Check format "local" date fields output' ' 439 + test_date local \ 440 + "Mon Jul 3 23:18:43 2006" \ 441 + "Mon Jul 3 23:18:44 2006" \ 442 + "Mon Jul 3 23:18:45 2006" 443 + ' 444 + 445 + test_expect_success 'Check format "iso8601" date fields output' ' 446 + test_date iso8601 \ 447 + "2006-07-04 01:18:43 +0200" \ 448 + "2006-07-04 01:18:44 +0200" \ 449 + "2006-07-04 01:18:45 +0200" 450 + ' 451 + 452 + test_expect_success 'Check format "iso8601-local" date fields output' ' 453 + test_date iso8601-local "2006-07-03 23:18:43 +0000" "2006-07-03 23:18:44 +0000" "2006-07-03 23:18:45 +0000" 454 + ' 455 + 456 + test_expect_success 'Check format "rfc2822" date fields output' ' 457 + test_date rfc2822 \ 458 + "Tue, 4 Jul 2006 01:18:43 +0200" \ 459 + "Tue, 4 Jul 2006 01:18:44 +0200" \ 460 + "Tue, 4 Jul 2006 01:18:45 +0200" 461 + ' 462 + 463 + test_expect_success 'Check format "rfc2822-local" date fields output' ' 464 + test_date rfc2822-local "Mon, 3 Jul 2006 23:18:43 +0000" "Mon, 3 Jul 2006 23:18:44 +0000" "Mon, 3 Jul 2006 23:18:45 +0000" 465 + ' 466 + 467 + test_expect_success 'Check format "raw" date fields output' ' 468 + test_date raw "1151968723 +0200" "1151968724 +0200" "1151968725 +0200" 469 + ' 470 + 471 + test_expect_success 'Check format "raw-local" date fields output' ' 472 + test_date raw-local "1151968723 +0000" "1151968724 +0000" "1151968725 +0000" 473 + ' 474 + 475 + test_expect_success 'Check format of strftime date fields' ' 476 + echo "my date is 2006-07-04" >expected && 477 + ${git_for_each_ref} \ 478 + --format="%(authordate:format:my date is %Y-%m-%d)" \ 479 + refs/heads >actual && 480 + test_cmp expected actual 481 + ' 482 + 483 + test_expect_success 'Check format of strftime-local date fields' ' 484 + echo "my date is 2006-07-03" >expected && 485 + ${git_for_each_ref} \ 486 + --format="%(authordate:format-local:my date is %Y-%m-%d)" \ 487 + refs/heads >actual && 488 + test_cmp expected actual 489 + ' 490 + 491 + test_expect_success 'exercise strftime with odd fields' ' 492 + echo >expected && 493 + ${git_for_each_ref} --format="%(authordate:format:)" refs/heads >actual && 494 + test_cmp expected actual && 495 + long="long format -- $ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID" && 496 + echo $long >expected && 497 + ${git_for_each_ref} --format="%(authordate:format:$long)" refs/heads >actual && 498 + test_cmp expected actual 499 + ' 500 + 501 + cat >expected <<\EOF 502 + refs/heads/main 503 + refs/remotes/origin/main 504 + refs/tags/testtag 505 + EOF 506 + 507 + test_expect_success 'Verify ascending sort' ' 508 + ${git_for_each_ref} --format="%(refname)" --sort=refname >actual && 509 + test_cmp expected actual 510 + ' 511 + 512 + 513 + cat >expected <<\EOF 514 + refs/tags/testtag 515 + refs/remotes/origin/main 516 + refs/heads/main 517 + EOF 518 + 519 + test_expect_success 'Verify descending sort' ' 520 + ${git_for_each_ref} --format="%(refname)" --sort=-refname >actual && 521 + test_cmp expected actual 522 + ' 523 + 524 + test_expect_success 'Give help even with invalid sort atoms' ' 525 + test_expect_code 129 ${git_for_each_ref} --sort=bogus -h >actual 2>&1 && 526 + grep "^usage: ${git_for_each_ref}" actual 527 + ' 528 + 529 + cat >expected <<\EOF 530 + refs/tags/testtag 531 + refs/tags/testtag-2 532 + EOF 533 + 534 + test_expect_success 'exercise patterns with prefixes' ' 535 + git tag testtag-2 && 536 + test_when_finished "git tag -d testtag-2" && 537 + ${git_for_each_ref} --format="%(refname)" \ 538 + refs/tags/testtag refs/tags/testtag-2 >actual && 539 + test_cmp expected actual 540 + ' 541 + 542 + cat >expected <<\EOF 543 + refs/tags/testtag 544 + refs/tags/testtag-2 545 + EOF 546 + 547 + test_expect_success 'exercise glob patterns with prefixes' ' 548 + git tag testtag-2 && 549 + test_when_finished "git tag -d testtag-2" && 550 + ${git_for_each_ref} --format="%(refname)" \ 551 + refs/tags/testtag "refs/tags/testtag-*" >actual && 552 + test_cmp expected actual 553 + ' 554 + 555 + cat >expected <<\EOF 556 + refs/tags/bar 557 + refs/tags/baz 558 + refs/tags/testtag 559 + EOF 560 + 561 + test_expect_success 'exercise patterns with prefix exclusions' ' 562 + for tag in foo/one foo/two foo/three bar baz 563 + do 564 + git tag "$tag" || return 1 565 + done && 566 + test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && 567 + ${git_for_each_ref} --format="%(refname)" \ 568 + refs/tags/ --exclude=refs/tags/foo >actual && 569 + test_cmp expected actual 570 + ' 571 + 572 + cat >expected <<\EOF 573 + refs/tags/bar 574 + refs/tags/baz 575 + refs/tags/foo/one 576 + refs/tags/testtag 577 + EOF 578 + 579 + test_expect_success 'exercise patterns with pattern exclusions' ' 580 + for tag in foo/one foo/two foo/three bar baz 581 + do 582 + git tag "$tag" || return 1 583 + done && 584 + test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && 585 + ${git_for_each_ref} --format="%(refname)" \ 586 + refs/tags/ --exclude="refs/tags/foo/t*" >actual && 587 + test_cmp expected actual 588 + ' 589 + 590 + cat >expected <<\EOF 591 + 'refs/heads/main' 592 + 'refs/remotes/origin/main' 593 + 'refs/tags/testtag' 594 + EOF 595 + 596 + test_expect_success 'Quoting style: shell' ' 597 + ${git_for_each_ref} --shell --format="%(refname)" >actual && 598 + test_cmp expected actual 599 + ' 600 + 601 + test_expect_success 'Quoting style: perl' ' 602 + ${git_for_each_ref} --perl --format="%(refname)" >actual && 603 + test_cmp expected actual 604 + ' 605 + 606 + test_expect_success 'Quoting style: python' ' 607 + ${git_for_each_ref} --python --format="%(refname)" >actual && 608 + test_cmp expected actual 609 + ' 610 + 611 + cat >expected <<\EOF 612 + "refs/heads/main" 613 + "refs/remotes/origin/main" 614 + "refs/tags/testtag" 615 + EOF 616 + 617 + test_expect_success 'Quoting style: tcl' ' 618 + ${git_for_each_ref} --tcl --format="%(refname)" >actual && 619 + test_cmp expected actual 620 + ' 621 + 622 + for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do 623 + test_expect_success "more than one quoting style: $i" " 624 + test_must_fail ${git_for_each_ref} $i 2>err && 625 + grep '^error: more than one quoting style' err 626 + " 627 + done 628 + 629 + test_expect_success 'setup for upstream:track[short]' ' 630 + test_commit two 631 + ' 632 + 633 + test_atom head upstream:track '[ahead 1]' 634 + test_atom head upstream:trackshort '>' 635 + test_atom head upstream:track,nobracket 'ahead 1' 636 + test_atom head upstream:nobracket,track 'ahead 1' 637 + 638 + test_expect_success 'setup for push:track[short]' ' 639 + test_commit third && 640 + git update-ref refs/remotes/myfork/main main && 641 + git reset main~1 642 + ' 643 + 644 + test_atom head push:track '[behind 1]' 645 + test_atom head push:trackshort '<' 646 + 647 + test_expect_success 'Check that :track[short] cannot be used with other atoms' ' 648 + test_must_fail ${git_for_each_ref} --format="%(refname:track)" 2>/dev/null && 649 + test_must_fail ${git_for_each_ref} --format="%(refname:trackshort)" 2>/dev/null 650 + ' 651 + 652 + test_expect_success 'Check that :track[short] works when upstream is invalid' ' 653 + cat >expected <<-\EOF && 654 + [gone] 655 + 656 + EOF 657 + test_when_finished "git config branch.main.merge refs/heads/main" && 658 + git config branch.main.merge refs/heads/does-not-exist && 659 + ${git_for_each_ref} \ 660 + --format="%(upstream:track)$LF%(upstream:trackshort)" \ 661 + refs/heads >actual && 662 + test_cmp expected actual 663 + ' 664 + 665 + test_expect_success 'Check for invalid refname format' ' 666 + test_must_fail ${git_for_each_ref} --format="%(refname:INVALID)" 667 + ' 668 + 669 + test_expect_success 'set up color tests' ' 670 + cat >expected.color <<-EOF && 671 + $(git rev-parse --short refs/heads/main) <GREEN>main<RESET> 672 + $(git rev-parse --short refs/remotes/myfork/main) <GREEN>myfork/main<RESET> 673 + $(git rev-parse --short refs/remotes/origin/main) <GREEN>origin/main<RESET> 674 + $(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET> 675 + $(git rev-parse --short refs/tags/third) <GREEN>third<RESET> 676 + $(git rev-parse --short refs/tags/two) <GREEN>two<RESET> 677 + EOF 678 + sed "s/<[^>]*>//g" <expected.color >expected.bare && 679 + color_format="%(objectname:short) %(color:green)%(refname:short)" 680 + ' 681 + 682 + test_expect_success TTY '%(color) shows color with a tty' ' 683 + test_terminal ${git_for_each_ref} --format="$color_format" >actual.raw && 684 + test_decode_color <actual.raw >actual && 685 + test_cmp expected.color actual 686 + ' 687 + 688 + test_expect_success '%(color) does not show color without tty' ' 689 + TERM=vt100 ${git_for_each_ref} --format="$color_format" >actual && 690 + test_cmp expected.bare actual 691 + ' 692 + 693 + test_expect_success '--color can override tty check' ' 694 + ${git_for_each_ref} --color --format="$color_format" >actual.raw && 695 + test_decode_color <actual.raw >actual && 696 + test_cmp expected.color actual 697 + ' 698 + 699 + test_expect_success 'color.ui=always does not override tty check' ' 700 + git -c color.ui=always ${git_for_each_ref#git} --format="$color_format" >actual && 701 + test_cmp expected.bare actual 702 + ' 703 + 704 + test_expect_success 'setup for describe atom tests' ' 705 + git init -b master describe-repo && 706 + ( 707 + cd describe-repo && 708 + 709 + test_commit --no-tag one && 710 + git tag tagone && 711 + 712 + test_commit --no-tag two && 713 + git tag -a -m "tag two" tagtwo 714 + ) 715 + ' 716 + 717 + test_expect_success 'describe atom vs git describe' ' 718 + ( 719 + cd describe-repo && 720 + 721 + ${git_for_each_ref} --format="%(objectname)" \ 722 + refs/tags/ >obj && 723 + while read hash 724 + do 725 + if desc=$(git describe $hash) 726 + then 727 + : >expect-contains-good 728 + else 729 + : >expect-contains-bad 730 + fi && 731 + echo "$hash $desc" || return 1 732 + done <obj >expect && 733 + test_path_exists expect-contains-good && 734 + test_path_exists expect-contains-bad && 735 + 736 + ${git_for_each_ref} --format="%(objectname) %(describe)" \ 737 + refs/tags/ >actual 2>err && 738 + test_cmp expect actual && 739 + test_must_be_empty err 740 + ) 741 + ' 742 + 743 + test_expect_success 'describe:tags vs describe --tags' ' 744 + ( 745 + cd describe-repo && 746 + git describe --tags >expect && 747 + ${git_for_each_ref} --format="%(describe:tags)" \ 748 + refs/heads/master >actual && 749 + test_cmp expect actual 750 + ) 751 + ' 752 + 753 + test_expect_success 'describe:abbrev=... vs describe --abbrev=...' ' 754 + ( 755 + cd describe-repo && 756 + 757 + # Case 1: We have commits between HEAD and the most 758 + # recent tag reachable from it 759 + test_commit --no-tag file && 760 + git describe --abbrev=14 >expect && 761 + ${git_for_each_ref} --format="%(describe:abbrev=14)" \ 762 + refs/heads/master >actual && 763 + test_cmp expect actual && 764 + 765 + # Make sure the hash used is at least 14 digits long 766 + sed -e "s/^.*-g\([0-9a-f]*\)$/\1/" <actual >hexpart && 767 + test 15 -le $(wc -c <hexpart) && 768 + 769 + # Case 2: We have a tag at HEAD, describe directly gives 770 + # the name of the tag 771 + git tag -a -m tagged tagname && 772 + git describe --abbrev=14 >expect && 773 + ${git_for_each_ref} --format="%(describe:abbrev=14)" \ 774 + refs/heads/master >actual && 775 + test_cmp expect actual && 776 + test tagname = $(cat actual) 777 + ) 778 + ' 779 + 780 + test_expect_success 'describe:match=... vs describe --match ...' ' 781 + ( 782 + cd describe-repo && 783 + git tag -a -m "tag foo" tag-foo && 784 + git describe --match "*-foo" >expect && 785 + ${git_for_each_ref} --format="%(describe:match="*-foo")" \ 786 + refs/heads/master >actual && 787 + test_cmp expect actual 788 + ) 789 + ' 790 + 791 + test_expect_success 'describe:exclude:... vs describe --exclude ...' ' 792 + ( 793 + cd describe-repo && 794 + git tag -a -m "tag bar" tag-bar && 795 + git describe --exclude "*-bar" >expect && 796 + ${git_for_each_ref} --format="%(describe:exclude="*-bar")" \ 797 + refs/heads/master >actual && 798 + test_cmp expect actual 799 + ) 800 + ' 801 + 802 + test_expect_success 'deref with describe atom' ' 803 + ( 804 + cd describe-repo && 805 + cat >expect <<-\EOF && 806 + 807 + tagname 808 + tagname 809 + tagname 810 + 811 + tagtwo 812 + EOF 813 + ${git_for_each_ref} --format="%(*describe)" >actual && 814 + test_cmp expect actual 815 + ) 816 + ' 817 + 818 + test_expect_success 'err on bad describe atom arg' ' 819 + ( 820 + cd describe-repo && 821 + 822 + # The bad arg is the only arg passed to describe atom 823 + cat >expect <<-\EOF && 824 + fatal: unrecognized %(describe) argument: baz 825 + EOF 826 + test_must_fail ${git_for_each_ref} --format="%(describe:baz)" \ 827 + refs/heads/master 2>actual && 828 + test_cmp expect actual && 829 + 830 + # The bad arg is in the middle of the option string 831 + # passed to the describe atom 832 + cat >expect <<-\EOF && 833 + fatal: unrecognized %(describe) argument: qux=1,abbrev=14 834 + EOF 835 + test_must_fail ${git_for_each_ref} \ 836 + --format="%(describe:tags,qux=1,abbrev=14)" \ 837 + ref/heads/master 2>actual && 838 + test_cmp expect actual 839 + ) 840 + ' 841 + 842 + cat >expected <<\EOF 843 + heads/main 844 + tags/main 845 + EOF 846 + 847 + test_expect_success 'Check ambiguous head and tag refs (strict)' ' 848 + git config --bool core.warnambiguousrefs true && 849 + git checkout -b newtag && 850 + echo "Using $datestamp" > one && 851 + git add one && 852 + git commit -m "Branch" && 853 + setdate_and_increment && 854 + git tag -m "Tagging at $datestamp" main && 855 + ${git_for_each_ref} --format "%(refname:short)" refs/heads/main refs/tags/main >actual && 856 + test_cmp expected actual 857 + ' 858 + 859 + cat >expected <<\EOF 860 + heads/main 861 + main 862 + EOF 863 + 864 + test_expect_success 'Check ambiguous head and tag refs (loose)' ' 865 + git config --bool core.warnambiguousrefs false && 866 + ${git_for_each_ref} --format "%(refname:short)" refs/heads/main refs/tags/main >actual && 867 + test_cmp expected actual 868 + ' 869 + 870 + cat >expected <<\EOF 871 + heads/ambiguous 872 + ambiguous 873 + EOF 874 + 875 + test_expect_success 'Check ambiguous head and tag refs II (loose)' ' 876 + git checkout main && 877 + git tag ambiguous testtag^0 && 878 + git branch ambiguous testtag^0 && 879 + ${git_for_each_ref} --format "%(refname:short)" refs/heads/ambiguous refs/tags/ambiguous >actual && 880 + test_cmp expected actual 881 + ' 882 + 883 + test_expect_success 'create tag without tagger' ' 884 + git tag -a -m "Broken tag" taggerless && 885 + git tag -f taggerless $(git cat-file tag taggerless | 886 + sed -e "/^tagger /d" | 887 + git hash-object --literally --stdin -w -t tag) 888 + ' 889 + 890 + test_atom refs/tags/taggerless type 'commit' 891 + test_atom refs/tags/taggerless tag 'taggerless' 892 + test_atom refs/tags/taggerless tagger '' 893 + test_atom refs/tags/taggerless taggername '' 894 + test_atom refs/tags/taggerless taggeremail '' 895 + test_atom refs/tags/taggerless taggeremail:trim '' 896 + test_atom refs/tags/taggerless taggeremail:localpart '' 897 + test_atom refs/tags/taggerless taggerdate '' 898 + test_atom refs/tags/taggerless committer '' 899 + test_atom refs/tags/taggerless committername '' 900 + test_atom refs/tags/taggerless committeremail '' 901 + test_atom refs/tags/taggerless committeremail:trim '' 902 + test_atom refs/tags/taggerless committeremail:localpart '' 903 + test_atom refs/tags/taggerless committerdate '' 904 + test_atom refs/tags/taggerless subject 'Broken tag' 905 + 906 + test_expect_success 'an unusual tag with an incomplete line' ' 907 + 908 + git tag -m "bogo" bogo && 909 + bogo=$(git cat-file tag bogo) && 910 + bogo=$(printf "%s" "$bogo" | git mktag) && 911 + git tag -f bogo "$bogo" && 912 + ${git_for_each_ref} --format "%(body)" refs/tags/bogo 913 + 914 + ' 915 + 916 + test_expect_success 'create tag with subject and body content' ' 917 + cat >>msg <<-\EOF && 918 + the subject line 919 + 920 + first body line 921 + second body line 922 + EOF 923 + git tag -F msg subject-body 924 + ' 925 + test_atom refs/tags/subject-body subject 'the subject line' 926 + test_atom refs/tags/subject-body subject:sanitize 'the-subject-line' 927 + test_atom refs/tags/subject-body body 'first body line 928 + second body line 929 + ' 930 + test_atom refs/tags/subject-body contents 'the subject line 931 + 932 + first body line 933 + second body line 934 + ' 935 + 936 + test_expect_success 'create tag with multiline subject' ' 937 + cat >msg <<-\EOF && 938 + first subject line 939 + second subject line 940 + 941 + first body line 942 + second body line 943 + EOF 944 + git tag -F msg multiline 945 + ' 946 + test_atom refs/tags/multiline subject 'first subject line second subject line' 947 + test_atom refs/tags/multiline subject:sanitize 'first-subject-line-second-subject-line' 948 + test_atom refs/tags/multiline contents:subject 'first subject line second subject line' 949 + test_atom refs/tags/multiline body 'first body line 950 + second body line 951 + ' 952 + test_atom refs/tags/multiline contents:body 'first body line 953 + second body line 954 + ' 955 + test_atom refs/tags/multiline contents:signature '' 956 + test_atom refs/tags/multiline contents 'first subject line 957 + second subject line 958 + 959 + first body line 960 + second body line 961 + ' 962 + 963 + test_expect_success GPG 'create signed tags' ' 964 + git tag -s -m "" signed-empty && 965 + git tag -s -m "subject line" signed-short && 966 + cat >msg <<-\EOF && 967 + subject line 968 + 969 + body contents 970 + EOF 971 + git tag -s -F msg signed-long 972 + ' 973 + 974 + sig='-----BEGIN PGP SIGNATURE----- 975 + -----END PGP SIGNATURE----- 976 + ' 977 + 978 + PREREQ=GPG 979 + test_atom refs/tags/signed-empty subject '' 980 + test_atom refs/tags/signed-empty subject:sanitize '' 981 + test_atom refs/tags/signed-empty contents:subject '' 982 + test_atom refs/tags/signed-empty body "$sig" 983 + test_atom refs/tags/signed-empty contents:body '' 984 + test_atom refs/tags/signed-empty contents:signature "$sig" 985 + test_atom refs/tags/signed-empty contents "$sig" 986 + 987 + test_expect_success GPG 'basic atom: refs/tags/signed-empty raw' ' 988 + git cat-file tag refs/tags/signed-empty >expected && 989 + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-empty >actual && 990 + sanitize_pgp <expected >expected.clean && 991 + echo >>expected.clean && 992 + sanitize_pgp <actual >actual.clean && 993 + test_cmp expected.clean actual.clean 994 + ' 995 + 996 + test_atom refs/tags/signed-short subject 'subject line' 997 + test_atom refs/tags/signed-short subject:sanitize 'subject-line' 998 + test_atom refs/tags/signed-short contents:subject 'subject line' 999 + test_atom refs/tags/signed-short body "$sig" 1000 + test_atom refs/tags/signed-short contents:body '' 1001 + test_atom refs/tags/signed-short contents:signature "$sig" 1002 + test_atom refs/tags/signed-short contents "subject line 1003 + $sig" 1004 + 1005 + test_expect_success GPG 'basic atom: refs/tags/signed-short raw' ' 1006 + git cat-file tag refs/tags/signed-short >expected && 1007 + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-short >actual && 1008 + sanitize_pgp <expected >expected.clean && 1009 + echo >>expected.clean && 1010 + sanitize_pgp <actual >actual.clean && 1011 + test_cmp expected.clean actual.clean 1012 + ' 1013 + 1014 + test_atom refs/tags/signed-long subject 'subject line' 1015 + test_atom refs/tags/signed-long subject:sanitize 'subject-line' 1016 + test_atom refs/tags/signed-long contents:subject 'subject line' 1017 + test_atom refs/tags/signed-long body "body contents 1018 + $sig" 1019 + test_atom refs/tags/signed-long contents:body 'body contents 1020 + ' 1021 + test_atom refs/tags/signed-long contents:signature "$sig" 1022 + test_atom refs/tags/signed-long contents "subject line 1023 + 1024 + body contents 1025 + $sig" 1026 + 1027 + test_expect_success GPG 'basic atom: refs/tags/signed-long raw' ' 1028 + git cat-file tag refs/tags/signed-long >expected && 1029 + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-long >actual && 1030 + sanitize_pgp <expected >expected.clean && 1031 + echo >>expected.clean && 1032 + sanitize_pgp <actual >actual.clean && 1033 + test_cmp expected.clean actual.clean 1034 + ' 1035 + 1036 + test_expect_success 'set up refs pointing to tree and blob' ' 1037 + git update-ref refs/mytrees/first refs/heads/main^{tree} && 1038 + git update-ref refs/myblobs/first refs/heads/main:one 1039 + ' 1040 + 1041 + test_atom refs/mytrees/first subject "" 1042 + test_atom refs/mytrees/first contents:subject "" 1043 + test_atom refs/mytrees/first body "" 1044 + test_atom refs/mytrees/first contents:body "" 1045 + test_atom refs/mytrees/first contents:signature "" 1046 + test_atom refs/mytrees/first contents "" 1047 + 1048 + test_expect_success 'basic atom: refs/mytrees/first raw' ' 1049 + git cat-file tree refs/mytrees/first >expected && 1050 + echo >>expected && 1051 + ${git_for_each_ref} --format="%(raw)" refs/mytrees/first >actual && 1052 + test_cmp expected actual && 1053 + git cat-file -s refs/mytrees/first >expected && 1054 + ${git_for_each_ref} --format="%(raw:size)" refs/mytrees/first >actual && 1055 + test_cmp expected actual 1056 + ' 1057 + 1058 + test_atom refs/myblobs/first subject "" 1059 + test_atom refs/myblobs/first contents:subject "" 1060 + test_atom refs/myblobs/first body "" 1061 + test_atom refs/myblobs/first contents:body "" 1062 + test_atom refs/myblobs/first contents:signature "" 1063 + test_atom refs/myblobs/first contents "" 1064 + 1065 + test_expect_success 'basic atom: refs/myblobs/first raw' ' 1066 + git cat-file blob refs/myblobs/first >expected && 1067 + echo >>expected && 1068 + ${git_for_each_ref} --format="%(raw)" refs/myblobs/first >actual && 1069 + test_cmp expected actual && 1070 + git cat-file -s refs/myblobs/first >expected && 1071 + ${git_for_each_ref} --format="%(raw:size)" refs/myblobs/first >actual && 1072 + test_cmp expected actual 1073 + ' 1074 + 1075 + test_expect_success 'set up refs pointing to binary blob' ' 1076 + printf "a\0b\0c" >blob1 && 1077 + printf "a\0c\0b" >blob2 && 1078 + printf "\0a\0b\0c" >blob3 && 1079 + printf "abc" >blob4 && 1080 + printf "\0 \0 \0 " >blob5 && 1081 + printf "\0 \0a\0 " >blob6 && 1082 + printf " " >blob7 && 1083 + >blob8 && 1084 + obj=$(git hash-object -w blob1) && 1085 + git update-ref refs/myblobs/blob1 "$obj" && 1086 + obj=$(git hash-object -w blob2) && 1087 + git update-ref refs/myblobs/blob2 "$obj" && 1088 + obj=$(git hash-object -w blob3) && 1089 + git update-ref refs/myblobs/blob3 "$obj" && 1090 + obj=$(git hash-object -w blob4) && 1091 + git update-ref refs/myblobs/blob4 "$obj" && 1092 + obj=$(git hash-object -w blob5) && 1093 + git update-ref refs/myblobs/blob5 "$obj" && 1094 + obj=$(git hash-object -w blob6) && 1095 + git update-ref refs/myblobs/blob6 "$obj" && 1096 + obj=$(git hash-object -w blob7) && 1097 + git update-ref refs/myblobs/blob7 "$obj" && 1098 + obj=$(git hash-object -w blob8) && 1099 + git update-ref refs/myblobs/blob8 "$obj" 1100 + ' 1101 + 1102 + test_expect_success 'Verify sorts with raw' ' 1103 + cat >expected <<-EOF && 1104 + refs/myblobs/blob8 1105 + refs/myblobs/blob5 1106 + refs/myblobs/blob6 1107 + refs/myblobs/blob3 1108 + refs/myblobs/blob7 1109 + refs/mytrees/first 1110 + refs/myblobs/first 1111 + refs/myblobs/blob1 1112 + refs/myblobs/blob2 1113 + refs/myblobs/blob4 1114 + refs/heads/main 1115 + EOF 1116 + ${git_for_each_ref} --format="%(refname)" --sort=raw \ 1117 + refs/heads/main refs/myblobs/ refs/mytrees/first >actual && 1118 + test_cmp expected actual 1119 + ' 1120 + 1121 + test_expect_success 'Verify sorts with raw:size' ' 1122 + cat >expected <<-EOF && 1123 + refs/myblobs/blob8 1124 + refs/myblobs/blob7 1125 + refs/myblobs/blob4 1126 + refs/myblobs/blob1 1127 + refs/myblobs/blob2 1128 + refs/myblobs/blob3 1129 + refs/myblobs/blob5 1130 + refs/myblobs/blob6 1131 + refs/myblobs/first 1132 + refs/mytrees/first 1133 + refs/heads/main 1134 + EOF 1135 + ${git_for_each_ref} --format="%(refname)" --sort=raw:size \ 1136 + refs/heads/main refs/myblobs/ refs/mytrees/first >actual && 1137 + test_cmp expected actual 1138 + ' 1139 + 1140 + test_expect_success 'validate raw atom with %(if:equals)' ' 1141 + cat >expected <<-EOF && 1142 + not equals 1143 + not equals 1144 + not equals 1145 + not equals 1146 + not equals 1147 + not equals 1148 + refs/myblobs/blob4 1149 + not equals 1150 + not equals 1151 + not equals 1152 + not equals 1153 + not equals 1154 + EOF 1155 + ${git_for_each_ref} --format="%(if:equals=abc)%(raw)%(then)%(refname)%(else)not equals%(end)" \ 1156 + refs/myblobs/ refs/heads/ >actual && 1157 + test_cmp expected actual 1158 + ' 1159 + 1160 + test_expect_success 'validate raw atom with %(if:notequals)' ' 1161 + cat >expected <<-EOF && 1162 + refs/heads/ambiguous 1163 + refs/heads/main 1164 + refs/heads/newtag 1165 + refs/myblobs/blob1 1166 + refs/myblobs/blob2 1167 + refs/myblobs/blob3 1168 + equals 1169 + refs/myblobs/blob5 1170 + refs/myblobs/blob6 1171 + refs/myblobs/blob7 1172 + refs/myblobs/blob8 1173 + refs/myblobs/first 1174 + EOF 1175 + ${git_for_each_ref} --format="%(if:notequals=abc)%(raw)%(then)%(refname)%(else)equals%(end)" \ 1176 + refs/myblobs/ refs/heads/ >actual && 1177 + test_cmp expected actual 1178 + ' 1179 + 1180 + test_expect_success 'empty raw refs with %(if)' ' 1181 + cat >expected <<-EOF && 1182 + refs/myblobs/blob1 not empty 1183 + refs/myblobs/blob2 not empty 1184 + refs/myblobs/blob3 not empty 1185 + refs/myblobs/blob4 not empty 1186 + refs/myblobs/blob5 not empty 1187 + refs/myblobs/blob6 not empty 1188 + refs/myblobs/blob7 empty 1189 + refs/myblobs/blob8 empty 1190 + refs/myblobs/first not empty 1191 + EOF 1192 + ${git_for_each_ref} --format="%(refname) %(if)%(raw)%(then)not empty%(else)empty%(end)" \ 1193 + refs/myblobs/ >actual && 1194 + test_cmp expected actual 1195 + ' 1196 + 1197 + test_expect_success '%(raw) with --python must fail' ' 1198 + test_must_fail ${git_for_each_ref} --format="%(raw)" --python 1199 + ' 1200 + 1201 + test_expect_success '%(raw) with --tcl must fail' ' 1202 + test_must_fail ${git_for_each_ref} --format="%(raw)" --tcl 1203 + ' 1204 + 1205 + test_expect_success PERL_TEST_HELPERS '%(raw) with --perl' ' 1206 + ${git_for_each_ref} --format="\$name= %(raw); 1207 + print \"\$name\"" refs/myblobs/blob1 --perl | perl >actual && 1208 + cmp blob1 actual && 1209 + ${git_for_each_ref} --format="\$name= %(raw); 1210 + print \"\$name\"" refs/myblobs/blob3 --perl | perl >actual && 1211 + cmp blob3 actual && 1212 + ${git_for_each_ref} --format="\$name= %(raw); 1213 + print \"\$name\"" refs/myblobs/blob8 --perl | perl >actual && 1214 + cmp blob8 actual && 1215 + ${git_for_each_ref} --format="\$name= %(raw); 1216 + print \"\$name\"" refs/myblobs/first --perl | perl >actual && 1217 + cmp one actual && 1218 + git cat-file tree refs/mytrees/first > expected && 1219 + ${git_for_each_ref} --format="\$name= %(raw); 1220 + print \"\$name\"" refs/mytrees/first --perl | perl >actual && 1221 + cmp expected actual 1222 + ' 1223 + 1224 + test_expect_success '%(raw) with --shell must fail' ' 1225 + test_must_fail ${git_for_each_ref} --format="%(raw)" --shell 1226 + ' 1227 + 1228 + test_expect_success '%(raw) with --shell and --sort=raw must fail' ' 1229 + test_must_fail ${git_for_each_ref} --format="%(raw)" --sort=raw --shell 1230 + ' 1231 + 1232 + test_expect_success '%(raw:size) with --shell' ' 1233 + ${git_for_each_ref} --format="%(raw:size)" | sed "s/^/$SQ/;s/$/$SQ/" >expect && 1234 + ${git_for_each_ref} --format="%(raw:size)" --shell >actual && 1235 + test_cmp expect actual 1236 + ' 1237 + 1238 + test_expect_success "${git_for_each_ref} --format compare with cat-file --batch" ' 1239 + git rev-parse refs/mytrees/first | git cat-file --batch >expected && 1240 + ${git_for_each_ref} --format="%(objectname) %(objecttype) %(objectsize) 1241 + %(raw)" refs/mytrees/first >actual && 1242 + test_cmp expected actual 1243 + ' 1244 + 1245 + test_expect_success 'verify sorts with contents:size' ' 1246 + cat >expect <<-\EOF && 1247 + refs/heads/main 1248 + refs/heads/newtag 1249 + refs/heads/ambiguous 1250 + EOF 1251 + ${git_for_each_ref} --format="%(refname)" \ 1252 + --sort=contents:size refs/heads/ >actual && 1253 + test_cmp expect actual 1254 + ' 1255 + 1256 + test_expect_success 'set up multiple-sort tags' ' 1257 + for when in 100000 200000 1258 + do 1259 + for email in user1 user2 1260 + do 1261 + for ref in ref1 ref2 1262 + do 1263 + GIT_COMMITTER_DATE="@$when +0000" \ 1264 + GIT_COMMITTER_EMAIL="$email@example.com" \ 1265 + git tag -m "tag $ref-$when-$email" \ 1266 + multi-$ref-$when-$email || return 1 1267 + done 1268 + done 1269 + done 1270 + ' 1271 + 1272 + test_expect_success 'Verify sort with multiple keys' ' 1273 + cat >expected <<-\EOF && 1274 + 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 1275 + 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 1276 + 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 1277 + 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 1278 + 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 1279 + 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 1280 + 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 1281 + 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 1282 + EOF 1283 + ${git_for_each_ref} \ 1284 + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ 1285 + --sort=-refname \ 1286 + --sort=taggeremail \ 1287 + --sort=taggerdate \ 1288 + "refs/tags/multi-*" >actual && 1289 + test_cmp expected actual 1290 + ' 1291 + 1292 + test_expect_success 'equivalent sorts fall back on refname' ' 1293 + cat >expected <<-\EOF && 1294 + 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 1295 + 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 1296 + 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 1297 + 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 1298 + 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 1299 + 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 1300 + 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 1301 + 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 1302 + EOF 1303 + ${git_for_each_ref} \ 1304 + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ 1305 + --sort=taggerdate \ 1306 + "refs/tags/multi-*" >actual && 1307 + test_cmp expected actual 1308 + ' 1309 + 1310 + test_expect_success '--no-sort cancels the previous sort keys' ' 1311 + cat >expected <<-\EOF && 1312 + 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 1313 + 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 1314 + 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 1315 + 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 1316 + 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 1317 + 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 1318 + 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 1319 + 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 1320 + EOF 1321 + ${git_for_each_ref} \ 1322 + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ 1323 + --sort=-refname \ 1324 + --sort=taggeremail \ 1325 + --no-sort \ 1326 + --sort=taggerdate \ 1327 + "refs/tags/multi-*" >actual && 1328 + test_cmp expected actual 1329 + ' 1330 + 1331 + test_expect_success '--no-sort without subsequent --sort prints expected refs' ' 1332 + cat >expected <<-\EOF && 1333 + refs/tags/multi-ref1-100000-user1 1334 + refs/tags/multi-ref1-100000-user2 1335 + refs/tags/multi-ref1-200000-user1 1336 + refs/tags/multi-ref1-200000-user2 1337 + refs/tags/multi-ref2-100000-user1 1338 + refs/tags/multi-ref2-100000-user2 1339 + refs/tags/multi-ref2-200000-user1 1340 + refs/tags/multi-ref2-200000-user2 1341 + EOF 1342 + 1343 + # Sort the results with `sort` for a consistent comparison against 1344 + # expected 1345 + ${git_for_each_ref} \ 1346 + --format="%(refname)" \ 1347 + --no-sort \ 1348 + "refs/tags/multi-*" | sort >actual && 1349 + test_cmp expected actual 1350 + ' 1351 + 1352 + test_expect_success 'set up custom date sorting' ' 1353 + # Dates: 1354 + # - Wed Feb 07 2024 21:34:20 +0000 1355 + # - Tue Dec 14 1999 00:05:22 +0000 1356 + # - Fri Jun 04 2021 11:26:51 +0000 1357 + # - Mon Jan 22 2007 16:44:01 GMT+0000 1358 + i=1 && 1359 + for when in 1707341660 945129922 1622806011 1169484241 1360 + do 1361 + GIT_COMMITTER_DATE="@$when +0000" \ 1362 + GIT_COMMITTER_EMAIL="user@example.com" \ 1363 + git tag -m "tag $when" custom-dates-$i && 1364 + i=$(($i+1)) || return 1 1365 + done 1366 + ' 1367 + 1368 + test_expect_success 'sort by date defaults to full timestamp' ' 1369 + cat >expected <<-\EOF && 1370 + 945129922 refs/tags/custom-dates-2 1371 + 1169484241 refs/tags/custom-dates-4 1372 + 1622806011 refs/tags/custom-dates-3 1373 + 1707341660 refs/tags/custom-dates-1 1374 + EOF 1375 + 1376 + ${git_for_each_ref} \ 1377 + --format="%(creatordate:unix) %(refname)" \ 1378 + --sort=creatordate \ 1379 + "refs/tags/custom-dates-*" >actual && 1380 + test_cmp expected actual 1381 + ' 1382 + 1383 + test_expect_success 'sort by custom date format' ' 1384 + cat >expected <<-\EOF && 1385 + 00:05:22 refs/tags/custom-dates-2 1386 + 11:26:51 refs/tags/custom-dates-3 1387 + 16:44:01 refs/tags/custom-dates-4 1388 + 21:34:20 refs/tags/custom-dates-1 1389 + EOF 1390 + 1391 + ${git_for_each_ref} \ 1392 + --format="%(creatordate:format:%H:%M:%S) %(refname)" \ 1393 + --sort="creatordate:format:%H:%M:%S" \ 1394 + "refs/tags/custom-dates-*" >actual && 1395 + test_cmp expected actual 1396 + ' 1397 + 1398 + test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' 1399 + test_when_finished "git checkout main" && 1400 + ${git_for_each_ref} --format="%(HEAD) %(refname:short)" refs/heads/ >actual && 1401 + sed -e "s/^\* / /" actual >expect && 1402 + git checkout --orphan orphaned-branch && 1403 + ${git_for_each_ref} --format="%(HEAD) %(refname:short)" refs/heads/ >actual && 1404 + test_cmp expect actual 1405 + ' 1406 + 1407 + cat >trailers <<EOF 1408 + Reviewed-by: A U Thor <author@example.com> 1409 + Signed-off-by: A U Thor <author@example.com> 1410 + [ v2 updated patch description ] 1411 + Acked-by: A U Thor 1412 + <author@example.com> 1413 + EOF 1414 + 1415 + unfold () { 1416 + perl -0pe 's/\n\s+/ /g' 1417 + } 1418 + 1419 + test_expect_success 'set up trailers for next test' ' 1420 + echo "Some contents" > two && 1421 + git add two && 1422 + git commit -F - <<-EOF 1423 + trailers: this commit message has trailers 1424 + 1425 + Some message contents 1426 + 1427 + $(cat trailers) 1428 + EOF 1429 + ' 1430 + 1431 + test_trailer_option () { 1432 + if test "$#" -eq 3 1433 + then 1434 + prereq="$1" 1435 + shift 1436 + fi && 1437 + title=$1 option=$2 1438 + cat >expect 1439 + test_expect_success $prereq "$title" ' 1440 + ${git_for_each_ref} --format="%($option)" refs/heads/main >actual && 1441 + test_cmp expect actual && 1442 + ${git_for_each_ref} --format="%(contents:$option)" refs/heads/main >actual && 1443 + test_cmp expect actual 1444 + ' 1445 + } 1446 + 1447 + test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) unfolds trailers' \ 1448 + 'trailers:unfold' <<-EOF 1449 + $(unfold <trailers) 1450 + 1451 + EOF 1452 + 1453 + test_trailer_option '%(trailers:only) shows only "key: value" trailers' \ 1454 + 'trailers:only' <<-EOF 1455 + $(grep -v patch.description <trailers) 1456 + 1457 + EOF 1458 + 1459 + test_trailer_option '%(trailers:only=no,only=true) shows only "key: value" trailers' \ 1460 + 'trailers:only=no,only=true' <<-EOF 1461 + $(grep -v patch.description <trailers) 1462 + 1463 + EOF 1464 + 1465 + test_trailer_option '%(trailers:only=yes) shows only "key: value" trailers' \ 1466 + 'trailers:only=yes' <<-EOF 1467 + $(grep -v patch.description <trailers) 1468 + 1469 + EOF 1470 + 1471 + test_trailer_option '%(trailers:only=no) shows all trailers' \ 1472 + 'trailers:only=no' <<-EOF 1473 + $(cat trailers) 1474 + 1475 + EOF 1476 + 1477 + test_trailer_option PERL_TEST_HELPERS '%(trailers:only) and %(trailers:unfold) work together' \ 1478 + 'trailers:only,unfold' <<-EOF 1479 + $(grep -v patch.description <trailers | unfold) 1480 + 1481 + EOF 1482 + 1483 + test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) and %(trailers:only) work together' \ 1484 + 'trailers:unfold,only' <<-EOF 1485 + $(grep -v patch.description <trailers | unfold) 1486 + 1487 + EOF 1488 + 1489 + test_trailer_option '%(trailers:key=foo) shows that trailer' \ 1490 + 'trailers:key=Signed-off-by' <<-EOF 1491 + Signed-off-by: A U Thor <author@example.com> 1492 + 1493 + EOF 1494 + 1495 + test_trailer_option '%(trailers:key=foo) is case insensitive' \ 1496 + 'trailers:key=SiGned-oFf-bY' <<-EOF 1497 + Signed-off-by: A U Thor <author@example.com> 1498 + 1499 + EOF 1500 + 1501 + test_trailer_option '%(trailers:key=foo:) trailing colon also works' \ 1502 + 'trailers:key=Signed-off-by:' <<-EOF 1503 + Signed-off-by: A U Thor <author@example.com> 1504 + 1505 + EOF 1506 + 1507 + test_trailer_option '%(trailers:key=foo) multiple keys' \ 1508 + 'trailers:key=Reviewed-by:,key=Signed-off-by' <<-EOF 1509 + Reviewed-by: A U Thor <author@example.com> 1510 + Signed-off-by: A U Thor <author@example.com> 1511 + 1512 + EOF 1513 + 1514 + test_trailer_option '%(trailers:key=nonexistent) becomes empty' \ 1515 + 'trailers:key=Shined-off-by:' <<-EOF 1516 + 1517 + EOF 1518 + 1519 + test_trailer_option '%(trailers:key=foo) handles multiple lines even if folded' \ 1520 + 'trailers:key=Acked-by' <<-EOF 1521 + $(grep -v patch.description <trailers | grep -v Signed-off-by | grep -v Reviewed-by) 1522 + 1523 + EOF 1524 + 1525 + test_trailer_option '%(trailers:key=foo,unfold) properly unfolds' \ 1526 + 'trailers:key=Signed-Off-by,unfold' <<-EOF 1527 + $(unfold <trailers | grep Signed-off-by) 1528 + 1529 + EOF 1530 + 1531 + test_trailer_option '%(trailers:key=foo,only=no) also includes nontrailer lines' \ 1532 + 'trailers:key=Signed-off-by,only=no' <<-EOF 1533 + Signed-off-by: A U Thor <author@example.com> 1534 + $(grep patch.description <trailers) 1535 + 1536 + EOF 1537 + 1538 + test_trailer_option '%(trailers:key=foo,valueonly) shows only value' \ 1539 + 'trailers:key=Signed-off-by,valueonly' <<-EOF 1540 + A U Thor <author@example.com> 1541 + 1542 + EOF 1543 + 1544 + test_trailer_option '%(trailers:separator) changes separator' \ 1545 + 'trailers:separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF 1546 + Reviewed-by: A U Thor <author@example.com>,Signed-off-by: A U Thor <author@example.com> 1547 + EOF 1548 + 1549 + test_trailer_option '%(trailers:key_value_separator) changes key-value separator' \ 1550 + 'trailers:key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF 1551 + Reviewed-by,A U Thor <author@example.com> 1552 + Signed-off-by,A U Thor <author@example.com> 1553 + 1554 + EOF 1555 + 1556 + test_trailer_option '%(trailers:separator,key_value_separator) changes both separators' \ 1557 + 'trailers:separator=%x2C,key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF 1558 + Reviewed-by,A U Thor <author@example.com>,Signed-off-by,A U Thor <author@example.com> 1559 + EOF 1560 + 1561 + test_expect_success 'multiple %(trailers) use their own options' ' 1562 + git tag -F - tag-with-trailers <<-\EOF && 1563 + body 1564 + 1565 + one: foo 1566 + one: bar 1567 + two: baz 1568 + two: qux 1569 + EOF 1570 + t1="%(trailers:key=one,key_value_separator=W,separator=X)" && 1571 + t2="%(trailers:key=two,key_value_separator=Y,separator=Z)" && 1572 + ${git_for_each_ref} --format="$t1%0a$t2" refs/tags/tag-with-trailers >actual && 1573 + cat >expect <<-\EOF && 1574 + oneWfooXoneWbar 1575 + twoYbazZtwoYqux 1576 + EOF 1577 + test_cmp expect actual 1578 + ' 1579 + 1580 + test_failing_trailer_option () { 1581 + title=$1 option=$2 1582 + cat >expect 1583 + test_expect_success "$title" ' 1584 + # error message cannot be checked under i18n 1585 + test_must_fail ${git_for_each_ref} --format="%($option)" refs/heads/main 2>actual && 1586 + test_cmp expect actual && 1587 + test_must_fail ${git_for_each_ref} --format="%(contents:$option)" refs/heads/main 2>actual && 1588 + test_cmp expect actual 1589 + ' 1590 + } 1591 + 1592 + test_failing_trailer_option '%(trailers) rejects unknown trailers arguments' \ 1593 + 'trailers:unsupported' <<-\EOF 1594 + fatal: unknown %(trailers) argument: unsupported 1595 + EOF 1596 + 1597 + test_failing_trailer_option '%(trailers:key) without value is error' \ 1598 + 'trailers:key' <<-\EOF 1599 + fatal: expected %(trailers:key=<value>) 1600 + EOF 1601 + 1602 + test_expect_success 'if arguments, %(contents:trailers) shows error if colon is missing' ' 1603 + cat >expect <<-EOF && 1604 + fatal: unrecognized %(contents) argument: trailersonly 1605 + EOF 1606 + test_must_fail ${git_for_each_ref} --format="%(contents:trailersonly)" 2>actual && 1607 + test_cmp expect actual 1608 + ' 1609 + 1610 + test_expect_success 'basic atom: head contents:trailers' ' 1611 + ${git_for_each_ref} --format="%(contents:trailers)" refs/heads/main >actual && 1612 + sanitize_pgp <actual >actual.clean && 1613 + # ${git_for_each_ref} ends with a blank line 1614 + cat >expect <<-EOF && 1615 + $(cat trailers) 1616 + 1617 + EOF 1618 + test_cmp expect actual.clean 1619 + ' 1620 + 1621 + test_expect_success 'basic atom: rest must fail' ' 1622 + test_must_fail ${git_for_each_ref} --format="%(rest)" refs/heads/main 1623 + ' 1624 + 1625 + test_expect_success 'HEAD atom does not take arguments' ' 1626 + test_must_fail ${git_for_each_ref} --format="%(HEAD:foo)" 2>err && 1627 + echo "fatal: %(HEAD) does not take arguments" >expect && 1628 + test_cmp expect err 1629 + ' 1630 + 1631 + test_expect_success 'subject atom rejects unknown arguments' ' 1632 + test_must_fail ${git_for_each_ref} --format="%(subject:foo)" 2>err && 1633 + echo "fatal: unrecognized %(subject) argument: foo" >expect && 1634 + test_cmp expect err 1635 + ' 1636 + 1637 + test_expect_success 'refname atom rejects unknown arguments' ' 1638 + test_must_fail ${git_for_each_ref} --format="%(refname:foo)" 2>err && 1639 + echo "fatal: unrecognized %(refname) argument: foo" >expect && 1640 + test_cmp expect err 1641 + ' 1642 + 1643 + test_expect_success 'trailer parsing not fooled by --- line' ' 1644 + git commit --allow-empty -F - <<-\EOF && 1645 + this is the subject 1646 + 1647 + This is the body. The message has a "---" line which would confuse a 1648 + message+patch parser. But here we know we have only a commit message, 1649 + so we get it right. 1650 + 1651 + trailer: wrong 1652 + --- 1653 + This is more body. 1654 + 1655 + trailer: right 1656 + EOF 1657 + 1658 + { 1659 + echo "trailer: right" && 1660 + echo 1661 + } >expect && 1662 + ${git_for_each_ref} --format="%(trailers)" refs/heads/main >actual && 1663 + test_cmp expect actual 1664 + ' 1665 + 1666 + test_expect_success 'Add symbolic ref for the following tests' ' 1667 + git symbolic-ref refs/heads/sym refs/heads/main 1668 + ' 1669 + 1670 + cat >expected <<EOF 1671 + refs/heads/main 1672 + EOF 1673 + 1674 + test_expect_success 'Verify usage of %(symref) atom' ' 1675 + ${git_for_each_ref} --format="%(symref)" refs/heads/sym >actual && 1676 + test_cmp expected actual 1677 + ' 1678 + 1679 + cat >expected <<EOF 1680 + heads/main 1681 + EOF 1682 + 1683 + test_expect_success 'Verify usage of %(symref:short) atom' ' 1684 + ${git_for_each_ref} --format="%(symref:short)" refs/heads/sym >actual && 1685 + test_cmp expected actual 1686 + ' 1687 + 1688 + cat >expected <<EOF 1689 + main 1690 + heads/main 1691 + EOF 1692 + 1693 + test_expect_success 'Verify usage of %(symref:lstrip) atom' ' 1694 + ${git_for_each_ref} --format="%(symref:lstrip=2)" refs/heads/sym > actual && 1695 + ${git_for_each_ref} --format="%(symref:lstrip=-2)" refs/heads/sym >> actual && 1696 + test_cmp expected actual && 1697 + 1698 + ${git_for_each_ref} --format="%(symref:strip=2)" refs/heads/sym > actual && 1699 + ${git_for_each_ref} --format="%(symref:strip=-2)" refs/heads/sym >> actual && 1700 + test_cmp expected actual 1701 + ' 1702 + 1703 + cat >expected <<EOF 1704 + refs 1705 + refs/heads 1706 + EOF 1707 + 1708 + test_expect_success 'Verify usage of %(symref:rstrip) atom' ' 1709 + ${git_for_each_ref} --format="%(symref:rstrip=2)" refs/heads/sym > actual && 1710 + ${git_for_each_ref} --format="%(symref:rstrip=-2)" refs/heads/sym >> actual && 1711 + test_cmp expected actual 1712 + ' 1713 + 1714 + test_expect_success ':remotename and :remoteref' ' 1715 + git init remote-tests && 1716 + ( 1717 + cd remote-tests && 1718 + test_commit initial && 1719 + git branch -M main && 1720 + git remote add from fifth.coffee:blub && 1721 + git config branch.main.remote from && 1722 + git config branch.main.merge refs/heads/stable && 1723 + git remote add to southridge.audio:repo && 1724 + git config remote.to.push "refs/heads/*:refs/heads/pushed/*" && 1725 + git config branch.main.pushRemote to && 1726 + for pair in "%(upstream)=refs/remotes/from/stable" \ 1727 + "%(upstream:remotename)=from" \ 1728 + "%(upstream:remoteref)=refs/heads/stable" \ 1729 + "%(push)=refs/remotes/to/pushed/main" \ 1730 + "%(push:remotename)=to" \ 1731 + "%(push:remoteref)=refs/heads/pushed/main" 1732 + do 1733 + echo "${pair#*=}" >expect && 1734 + ${git_for_each_ref} --format="${pair%=*}" \ 1735 + refs/heads/main >actual && 1736 + test_cmp expect actual || exit 1 1737 + done && 1738 + git branch push-simple && 1739 + git config branch.push-simple.pushRemote from && 1740 + actual="$(${git_for_each_ref} \ 1741 + --format="%(push:remotename),%(push:remoteref)" \ 1742 + refs/heads/push-simple)" && 1743 + test from, = "$actual" 1744 + ) 1745 + ' 1746 + 1747 + test_expect_success "${git_for_each_ref} --ignore-case ignores case" ' 1748 + ${git_for_each_ref} --format="%(refname)" refs/heads/MAIN >actual && 1749 + test_must_be_empty actual && 1750 + 1751 + echo refs/heads/main >expect && 1752 + ${git_for_each_ref} --format="%(refname)" --ignore-case \ 1753 + refs/heads/MAIN >actual && 1754 + test_cmp expect actual 1755 + ' 1756 + 1757 + test_expect_success "${git_for_each_ref} --omit-empty works" ' 1758 + ${git_for_each_ref} --format="%(refname)" >actual && 1759 + test_line_count -gt 1 actual && 1760 + ${git_for_each_ref} --format="%(if:equals=refs/heads/main)%(refname)%(then)%(refname)%(end)" --omit-empty >actual && 1761 + echo refs/heads/main >expect && 1762 + test_cmp expect actual 1763 + ' 1764 + 1765 + test_expect_success "${git_for_each_ref} --ignore-case works on multiple sort keys" ' 1766 + # name refs numerically to avoid case-insensitive filesystem conflicts 1767 + nr=0 && 1768 + for email in a A b B 1769 + do 1770 + for subject in a A b B 1771 + do 1772 + GIT_COMMITTER_EMAIL="$email@example.com" \ 1773 + git tag -m "tag $subject" icase-$(printf %02d $nr) && 1774 + nr=$((nr+1))|| 1775 + return 1 1776 + done 1777 + done && 1778 + ${git_for_each_ref} --ignore-case \ 1779 + --format="%(taggeremail) %(subject) %(refname)" \ 1780 + --sort=refname \ 1781 + --sort=subject \ 1782 + --sort=taggeremail \ 1783 + refs/tags/icase-* >actual && 1784 + cat >expect <<-\EOF && 1785 + <a@example.com> tag a refs/tags/icase-00 1786 + <a@example.com> tag A refs/tags/icase-01 1787 + <A@example.com> tag a refs/tags/icase-04 1788 + <A@example.com> tag A refs/tags/icase-05 1789 + <a@example.com> tag b refs/tags/icase-02 1790 + <a@example.com> tag B refs/tags/icase-03 1791 + <A@example.com> tag b refs/tags/icase-06 1792 + <A@example.com> tag B refs/tags/icase-07 1793 + <b@example.com> tag a refs/tags/icase-08 1794 + <b@example.com> tag A refs/tags/icase-09 1795 + <B@example.com> tag a refs/tags/icase-12 1796 + <B@example.com> tag A refs/tags/icase-13 1797 + <b@example.com> tag b refs/tags/icase-10 1798 + <b@example.com> tag B refs/tags/icase-11 1799 + <B@example.com> tag b refs/tags/icase-14 1800 + <B@example.com> tag B refs/tags/icase-15 1801 + EOF 1802 + test_cmp expect actual 1803 + ' 1804 + 1805 + test_expect_success "${git_for_each_ref} reports broken tags" ' 1806 + git tag -m "good tag" broken-tag-good HEAD && 1807 + git cat-file tag broken-tag-good >good && 1808 + sed s/commit/blob/ <good >bad && 1809 + bad=$(git hash-object -w -t tag bad) && 1810 + git update-ref refs/tags/broken-tag-bad $bad && 1811 + test_must_fail ${git_for_each_ref} --format="%(*objectname)" \ 1812 + refs/tags/broken-tag-* 1813 + ' 1814 + 1815 + test_expect_success 'set up tag with signature and no blank lines' ' 1816 + git tag -F - fake-sig-no-blanks <<-\EOF 1817 + this is the subject 1818 + -----BEGIN PGP SIGNATURE----- 1819 + not a real signature, but we just care about the 1820 + subject/body parsing. It is important here that 1821 + there are no blank lines in the signature. 1822 + -----END PGP SIGNATURE----- 1823 + EOF 1824 + ' 1825 + 1826 + test_atom refs/tags/fake-sig-no-blanks contents:subject 'this is the subject' 1827 + test_atom refs/tags/fake-sig-no-blanks contents:body '' 1828 + test_atom refs/tags/fake-sig-no-blanks contents:signature "$sig" 1829 + 1830 + test_expect_success 'set up tag with CRLF signature' ' 1831 + append_cr <<-\EOF | 1832 + this is the subject 1833 + -----BEGIN PGP SIGNATURE----- 1834 + 1835 + not a real signature, but we just care about 1836 + the subject/body parsing. It is important here 1837 + that there is a blank line separating this 1838 + from the signature header. 1839 + -----END PGP SIGNATURE----- 1840 + EOF 1841 + git tag -F - --cleanup=verbatim fake-sig-crlf 1842 + ' 1843 + 1844 + test_atom refs/tags/fake-sig-crlf contents:subject 'this is the subject' 1845 + test_atom refs/tags/fake-sig-crlf contents:body '' 1846 + 1847 + # CRLF is retained in the signature, so we have to pass our expected value 1848 + # through append_cr. But test_atom requires a shell string, which means command 1849 + # substitution, and the shell will strip trailing newlines from the output of 1850 + # the substitution. Hack around it by adding and then removing a dummy line. 1851 + sig_crlf="$(printf "%s" "$sig" | append_cr; echo dummy)" 1852 + sig_crlf=${sig_crlf%dummy} 1853 + test_atom refs/tags/fake-sig-crlf contents:signature "$sig_crlf" 1854 + 1855 + test_expect_success 'set up tag with signature and trailers' ' 1856 + git tag -F - fake-sig-trailer <<-\EOF 1857 + this is the subject 1858 + 1859 + this is the body 1860 + 1861 + My-Trailer: foo 1862 + -----BEGIN PGP SIGNATURE----- 1863 + 1864 + not a real signature, but we just care about the 1865 + subject/body/trailer parsing. 1866 + -----END PGP SIGNATURE----- 1867 + EOF 1868 + ' 1869 + 1870 + # use "separator=" here to suppress the terminating newline 1871 + test_atom refs/tags/fake-sig-trailer trailers:separator= 'My-Trailer: foo' 1872 + 1873 + test_expect_success "${git_for_each_ref} --stdin: empty" ' 1874 + >in && 1875 + ${git_for_each_ref} --format="%(refname)" --stdin <in >actual && 1876 + ${git_for_each_ref} --format="%(refname)" >expect && 1877 + test_cmp expect actual 1878 + ' 1879 + 1880 + test_expect_success "${git_for_each_ref} --stdin: fails if extra args" ' 1881 + >in && 1882 + test_must_fail ${git_for_each_ref} --format="%(refname)" \ 1883 + --stdin refs/heads/extra <in 2>err && 1884 + grep "unknown arguments supplied with --stdin" err 1885 + ' 1886 + 1887 + test_expect_success "${git_for_each_ref} --stdin: matches" ' 1888 + cat >in <<-EOF && 1889 + refs/tags/multi* 1890 + refs/heads/amb* 1891 + EOF 1892 + 1893 + cat >expect <<-EOF && 1894 + refs/heads/ambiguous 1895 + refs/tags/multi-ref1-100000-user1 1896 + refs/tags/multi-ref1-100000-user2 1897 + refs/tags/multi-ref1-200000-user1 1898 + refs/tags/multi-ref1-200000-user2 1899 + refs/tags/multi-ref2-100000-user1 1900 + refs/tags/multi-ref2-100000-user2 1901 + refs/tags/multi-ref2-200000-user1 1902 + refs/tags/multi-ref2-200000-user2 1903 + refs/tags/multiline 1904 + EOF 1905 + 1906 + ${git_for_each_ref} --format="%(refname)" --stdin <in >actual && 1907 + test_cmp expect actual 1908 + ' 1909 + 1910 + test_expect_success "${git_for_each_ref} with non-existing refs" ' 1911 + cat >in <<-EOF && 1912 + refs/heads/this-ref-does-not-exist 1913 + refs/tags/bogus 1914 + EOF 1915 + 1916 + ${git_for_each_ref} --format="%(refname)" --stdin <in >actual && 1917 + test_must_be_empty actual && 1918 + 1919 + xargs ${git_for_each_ref} --format="%(refname)" <in >actual && 1920 + test_must_be_empty actual 1921 + ' 1922 + 1923 + test_expect_success "${git_for_each_ref} with nested tags" ' 1924 + git tag -am "Normal tag" nested/base HEAD && 1925 + git tag -am "Nested tag" nested/nest1 refs/tags/nested/base && 1926 + git tag -am "Double nested tag" nested/nest2 refs/tags/nested/nest1 && 1927 + 1928 + head_oid="$(git rev-parse HEAD)" && 1929 + base_tag_oid="$(git rev-parse refs/tags/nested/base)" && 1930 + nest1_tag_oid="$(git rev-parse refs/tags/nested/nest1)" && 1931 + nest2_tag_oid="$(git rev-parse refs/tags/nested/nest2)" && 1932 + 1933 + cat >expect <<-EOF && 1934 + refs/tags/nested/base $base_tag_oid tag $head_oid commit 1935 + refs/tags/nested/nest1 $nest1_tag_oid tag $head_oid commit 1936 + refs/tags/nested/nest2 $nest2_tag_oid tag $head_oid commit 1937 + EOF 1938 + 1939 + ${git_for_each_ref} \ 1940 + --format="%(refname) %(objectname) %(objecttype) %(*objectname) %(*objecttype)" \ 1941 + refs/tags/nested/ >actual && 1942 + test_cmp expect actual 1943 + ' 1944 + 1945 + test_expect_success 'is-base atom with non-commits' ' 1946 + ${git_for_each_ref} --format="%(is-base:HEAD) %(refname)" >out 2>err && 1947 + grep "(HEAD) refs/heads/main" out && 1948 + 1949 + test_line_count = 2 err && 1950 + grep "error: object .* is a commit, not a blob" err && 1951 + grep "error: bad tag pointer to" err 1952 + ' 1953 + 1954 + GRADE_FORMAT="%(signature:grade)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" 1955 + TRUSTLEVEL_FORMAT="%(signature:trustlevel)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" 1956 + 1957 + test_expect_success GPG 'setup for signature atom using gpg' ' 1958 + git checkout -b signed && 1959 + 1960 + test_when_finished "test_unconfig commit.gpgSign" && 1961 + 1962 + echo "1" >file && 1963 + git add file && 1964 + test_tick && 1965 + git commit -S -m "file: 1" && 1966 + git tag first-signed && 1967 + 1968 + echo "2" >file && 1969 + test_tick && 1970 + git commit -a -m "file: 2" && 1971 + git tag second-unsigned && 1972 + 1973 + git config commit.gpgSign 1 && 1974 + echo "3" >file && 1975 + test_tick && 1976 + git commit -a --no-gpg-sign -m "file: 3" && 1977 + git tag third-unsigned && 1978 + 1979 + test_tick && 1980 + git rebase -f HEAD^^ && git tag second-signed HEAD^ && 1981 + git tag third-signed && 1982 + 1983 + echo "4" >file && 1984 + test_tick && 1985 + git commit -a -SB7227189 -m "file: 4" && 1986 + git tag fourth-signed && 1987 + 1988 + echo "5" >file && 1989 + test_tick && 1990 + git commit -a --no-gpg-sign -m "file: 5" && 1991 + git tag fifth-unsigned && 1992 + 1993 + echo "6" >file && 1994 + test_tick && 1995 + git commit -a --no-gpg-sign -m "file: 6" && 1996 + 1997 + test_tick && 1998 + git rebase -f HEAD^^ && 1999 + git tag fifth-signed HEAD^ && 2000 + git tag sixth-signed && 2001 + 2002 + echo "7" >file && 2003 + test_tick && 2004 + git commit -a --no-gpg-sign -m "file: 7" && 2005 + git tag seventh-unsigned 2006 + ' 2007 + 2008 + test_expect_success GPGSSH 'setup for signature atom using ssh' ' 2009 + test_when_finished "test_unconfig gpg.format user.signingkey" && 2010 + 2011 + test_config gpg.format ssh && 2012 + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && 2013 + echo "8" >file && 2014 + test_tick && 2015 + git add file && 2016 + git commit -S -m "file: 8" && 2017 + git tag eighth-signed-ssh 2018 + ' 2019 + 2020 + test_expect_success GPG2 'bare signature atom' ' 2021 + git verify-commit first-signed 2>expect && 2022 + echo >>expect && 2023 + ${git_for_each_ref} refs/tags/first-signed \ 2024 + --format="%(signature)" >actual && 2025 + test_cmp expect actual 2026 + ' 2027 + 2028 + test_expect_success GPG 'show good signature with custom format' ' 2029 + git verify-commit first-signed && 2030 + cat >expect <<-\EOF && 2031 + G 2032 + 13B6F51ECDDE430D 2033 + C O Mitter <committer@example.com> 2034 + 73D758744BE721698EC54E8713B6F51ECDDE430D 2035 + 73D758744BE721698EC54E8713B6F51ECDDE430D 2036 + EOF 2037 + ${git_for_each_ref} refs/tags/first-signed \ 2038 + --format="$GRADE_FORMAT" >actual && 2039 + test_cmp expect actual 2040 + ' 2041 + test_expect_success GPGSSH 'show good signature with custom format with ssh' ' 2042 + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && 2043 + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && 2044 + cat >expect.tmpl <<-\EOF && 2045 + G 2046 + FINGERPRINT 2047 + principal with number 1 2048 + FINGERPRINT 2049 + 2050 + EOF 2051 + sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && 2052 + ${git_for_each_ref} refs/tags/eighth-signed-ssh \ 2053 + --format="$GRADE_FORMAT" >actual && 2054 + test_cmp expect actual 2055 + ' 2056 + 2057 + test_expect_success GPG 'signature atom with grade option and bad signature' ' 2058 + git cat-file commit third-signed >raw && 2059 + sed -e "s/^file: 3/file: 3 forged/" raw >forged1 && 2060 + FORGED1=$(git hash-object -w -t commit forged1) && 2061 + git update-ref refs/tags/third-signed "$FORGED1" && 2062 + test_must_fail git verify-commit "$FORGED1" && 2063 + 2064 + cat >expect <<-\EOF && 2065 + B 2066 + 13B6F51ECDDE430D 2067 + C O Mitter <committer@example.com> 2068 + 2069 + 2070 + EOF 2071 + ${git_for_each_ref} refs/tags/third-signed \ 2072 + --format="$GRADE_FORMAT" >actual && 2073 + test_cmp expect actual 2074 + ' 2075 + 2076 + test_expect_success GPG 'show untrusted signature with custom format' ' 2077 + cat >expect <<-\EOF && 2078 + U 2079 + 65A0EEA02E30CAD7 2080 + Eris Discordia <discord@example.net> 2081 + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 2082 + D4BE22311AD3131E5EDA29A461092E85B7227189 2083 + EOF 2084 + ${git_for_each_ref} refs/tags/fourth-signed \ 2085 + --format="$GRADE_FORMAT" >actual && 2086 + test_cmp expect actual 2087 + ' 2088 + 2089 + test_expect_success GPG 'show untrusted signature with undefined trust level' ' 2090 + cat >expect <<-\EOF && 2091 + undefined 2092 + 65A0EEA02E30CAD7 2093 + Eris Discordia <discord@example.net> 2094 + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 2095 + D4BE22311AD3131E5EDA29A461092E85B7227189 2096 + EOF 2097 + ${git_for_each_ref} refs/tags/fourth-signed \ 2098 + --format="$TRUSTLEVEL_FORMAT" >actual && 2099 + test_cmp expect actual 2100 + ' 2101 + 2102 + test_expect_success GPG 'show untrusted signature with ultimate trust level' ' 2103 + cat >expect <<-\EOF && 2104 + ultimate 2105 + 13B6F51ECDDE430D 2106 + C O Mitter <committer@example.com> 2107 + 73D758744BE721698EC54E8713B6F51ECDDE430D 2108 + 73D758744BE721698EC54E8713B6F51ECDDE430D 2109 + EOF 2110 + ${git_for_each_ref} refs/tags/sixth-signed \ 2111 + --format="$TRUSTLEVEL_FORMAT" >actual && 2112 + test_cmp expect actual 2113 + ' 2114 + 2115 + test_expect_success GPG 'show unknown signature with custom format' ' 2116 + cat >expect <<-\EOF && 2117 + E 2118 + 13B6F51ECDDE430D 2119 + 2120 + 2121 + 2122 + EOF 2123 + GNUPGHOME="$GNUPGHOME_NOT_USED" ${git_for_each_ref} \ 2124 + refs/tags/sixth-signed --format="$GRADE_FORMAT" >actual && 2125 + test_cmp expect actual 2126 + ' 2127 + 2128 + test_expect_success GPG 'show lack of signature with custom format' ' 2129 + cat >expect <<-\EOF && 2130 + N 2131 + 2132 + 2133 + 2134 + 2135 + EOF 2136 + ${git_for_each_ref} refs/tags/seventh-unsigned \ 2137 + --format="$GRADE_FORMAT" >actual && 2138 + test_cmp expect actual 2139 + ' 2140 + 2141 + test_done
+2 -2138
t/t6300-for-each-ref.sh
··· 6 6 test_description='for-each-ref test' 7 7 8 8 . ./test-lib.sh 9 - GNUPGHOME_NOT_USED=$GNUPGHOME 10 - . "$TEST_DIRECTORY"/lib-gpg.sh 11 - . "$TEST_DIRECTORY"/lib-terminal.sh 12 9 13 - # Mon Jul 3 23:18:43 2006 +0000 14 - datestamp=1151968723 15 - setdate_and_increment () { 16 - GIT_COMMITTER_DATE="$datestamp +0200" 17 - datestamp=$(expr "$datestamp" + 1) 18 - GIT_AUTHOR_DATE="$datestamp +0200" 19 - datestamp=$(expr "$datestamp" + 1) 20 - export GIT_COMMITTER_DATE GIT_AUTHOR_DATE 21 - } 22 - 23 - test_object_file_size () { 24 - oid=$(git rev-parse "$1") 25 - path=".git/objects/$(test_oid_to_path $oid)" 26 - test_file_size "$path" 27 - } 28 - 29 - test_expect_success setup ' 30 - # setup .mailmap 31 - cat >.mailmap <<-EOF && 32 - A Thor <athor@example.com> A U Thor <author@example.com> 33 - C Mitter <cmitter@example.com> C O Mitter <committer@example.com> 34 - EOF 35 - 36 - setdate_and_increment && 37 - echo "Using $datestamp" > one && 38 - git add one && 39 - git commit -m "Initial" && 40 - git branch -M main && 41 - setdate_and_increment && 42 - git tag -a -m "Tagging at $datestamp" testtag && 43 - git update-ref refs/remotes/origin/main main && 44 - git remote add origin nowhere && 45 - git config branch.main.remote origin && 46 - git config branch.main.merge refs/heads/main && 47 - git remote add myfork elsewhere && 48 - git config remote.pushdefault myfork && 49 - git config push.default current 50 - ' 51 - 52 - test_atom () { 53 - case "$1" in 54 - head) ref=refs/heads/main ;; 55 - tag) ref=refs/tags/testtag ;; 56 - sym) ref=refs/heads/sym ;; 57 - *) ref=$1 ;; 58 - esac 59 - format=$2 60 - test_do=test_expect_${4:-success} 61 - 62 - printf '%s\n' "$3" >expected 63 - $test_do $PREREQ "basic atom: $ref $format" ' 64 - git for-each-ref --format="%($format)" "$ref" >actual && 65 - sanitize_pgp <actual >actual.clean && 66 - test_cmp expected actual.clean 67 - ' 68 - 69 - # Automatically test "contents:size" atom after testing "contents" 70 - if test "$format" = "contents" 71 - then 72 - # for commit leg, $3 is changed there 73 - expect=$(printf '%s' "$3" | wc -c) 74 - $test_do $PREREQ "basic atom: $ref contents:size" ' 75 - type=$(git cat-file -t "$ref") && 76 - case $type in 77 - tag) 78 - # We cannot use $3 as it expects sanitize_pgp to run 79 - git cat-file tag $ref >out && 80 - expect=$(tail -n +6 out | wc -c) && 81 - rm -f out ;; 82 - tree | blob) 83 - expect="" ;; 84 - commit) 85 - : "use the calculated expect" ;; 86 - *) 87 - BUG "unknown object type" ;; 88 - esac && 89 - # Leave $expect unquoted to lose possible leading whitespaces 90 - echo $expect >expected && 91 - git for-each-ref --format="%(contents:size)" "$ref" >actual && 92 - test_cmp expected actual 93 - ' 94 - fi 95 - } 96 - 97 - hexlen=$(test_oid hexsz) 98 - 99 - test_atom head refname refs/heads/main 100 - test_atom head refname: refs/heads/main 101 - test_atom head refname:short main 102 - test_atom head refname:lstrip=1 heads/main 103 - test_atom head refname:lstrip=2 main 104 - test_atom head refname:lstrip=-1 main 105 - test_atom head refname:lstrip=-2 heads/main 106 - test_atom head refname:rstrip=1 refs/heads 107 - test_atom head refname:rstrip=2 refs 108 - test_atom head refname:rstrip=-1 refs 109 - test_atom head refname:rstrip=-2 refs/heads 110 - test_atom head refname:strip=1 heads/main 111 - test_atom head refname:strip=2 main 112 - test_atom head refname:strip=-1 main 113 - test_atom head refname:strip=-2 heads/main 114 - test_atom head upstream refs/remotes/origin/main 115 - test_atom head upstream:short origin/main 116 - test_atom head upstream:lstrip=2 origin/main 117 - test_atom head upstream:lstrip=-2 origin/main 118 - test_atom head upstream:rstrip=2 refs/remotes 119 - test_atom head upstream:rstrip=-2 refs/remotes 120 - test_atom head upstream:strip=2 origin/main 121 - test_atom head upstream:strip=-2 origin/main 122 - test_atom head push refs/remotes/myfork/main 123 - test_atom head push:short myfork/main 124 - test_atom head push:lstrip=1 remotes/myfork/main 125 - test_atom head push:lstrip=-1 main 126 - test_atom head push:rstrip=1 refs/remotes/myfork 127 - test_atom head push:rstrip=-1 refs 128 - test_atom head push:strip=1 remotes/myfork/main 129 - test_atom head push:strip=-1 main 130 - test_atom head objecttype commit 131 - test_atom head objectsize $((131 + hexlen)) 132 - test_atom head objectsize:disk $(test_object_file_size refs/heads/main) 133 - test_atom head deltabase $ZERO_OID 134 - test_atom head objectname $(git rev-parse refs/heads/main) 135 - test_atom head objectname:short $(git rev-parse --short refs/heads/main) 136 - test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) 137 - test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) 138 - test_atom head tree $(git rev-parse refs/heads/main^{tree}) 139 - test_atom head tree:short $(git rev-parse --short refs/heads/main^{tree}) 140 - test_atom head tree:short=1 $(git rev-parse --short=1 refs/heads/main^{tree}) 141 - test_atom head tree:short=10 $(git rev-parse --short=10 refs/heads/main^{tree}) 142 - test_atom head parent '' 143 - test_atom head parent:short '' 144 - test_atom head parent:short=1 '' 145 - test_atom head parent:short=10 '' 146 - test_atom head numparent 0 147 - test_atom head object '' 148 - test_atom head type '' 149 - test_atom head raw "$(git cat-file commit refs/heads/main) 150 - " 151 - test_atom head '*objectname' '' 152 - test_atom head '*objecttype' '' 153 - test_atom head author 'A U Thor <author@example.com> 1151968724 +0200' 154 - test_atom head authorname 'A U Thor' 155 - test_atom head authorname:mailmap 'A Thor' 156 - test_atom head authoremail '<author@example.com>' 157 - test_atom head authoremail:trim 'author@example.com' 158 - test_atom head authoremail:localpart 'author' 159 - test_atom head authoremail:trim,localpart 'author' 160 - test_atom head authoremail:mailmap '<athor@example.com>' 161 - test_atom head authoremail:mailmap,trim 'athor@example.com' 162 - test_atom head authoremail:trim,mailmap 'athor@example.com' 163 - test_atom head authoremail:mailmap,localpart 'athor' 164 - test_atom head authoremail:localpart,mailmap 'athor' 165 - test_atom head authoremail:mailmap,trim,localpart,mailmap,trim 'athor' 166 - test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200' 167 - test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200' 168 - test_atom head committername 'C O Mitter' 169 - test_atom head committername:mailmap 'C Mitter' 170 - test_atom head committeremail '<committer@example.com>' 171 - test_atom head committeremail:trim 'committer@example.com' 172 - test_atom head committeremail:localpart 'committer' 173 - test_atom head committeremail:localpart,trim 'committer' 174 - test_atom head committeremail:mailmap '<cmitter@example.com>' 175 - test_atom head committeremail:mailmap,trim 'cmitter@example.com' 176 - test_atom head committeremail:trim,mailmap 'cmitter@example.com' 177 - test_atom head committeremail:mailmap,localpart 'cmitter' 178 - test_atom head committeremail:localpart,mailmap 'cmitter' 179 - test_atom head committeremail:trim,mailmap,trim,trim,localpart 'cmitter' 180 - test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200' 181 - test_atom head tag '' 182 - test_atom head tagger '' 183 - test_atom head taggername '' 184 - test_atom head taggeremail '' 185 - test_atom head taggeremail:trim '' 186 - test_atom head taggeremail:localpart '' 187 - test_atom head taggerdate '' 188 - test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200' 189 - test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200' 190 - test_atom head subject 'Initial' 191 - test_atom head subject:sanitize 'Initial' 192 - test_atom head contents:subject 'Initial' 193 - test_atom head body '' 194 - test_atom head contents:body '' 195 - test_atom head contents:signature '' 196 - test_atom head contents 'Initial 197 - ' 198 - test_atom head HEAD '*' 199 - 200 - test_atom tag refname refs/tags/testtag 201 - test_atom tag refname:short testtag 202 - test_atom tag upstream '' 203 - test_atom tag push '' 204 - test_atom tag objecttype tag 205 - test_atom tag objectsize $((114 + hexlen)) 206 - test_atom tag objectsize:disk $(test_object_file_size refs/tags/testtag) 207 - test_atom tag '*objectsize:disk' $(test_object_file_size refs/heads/main) 208 - test_atom tag deltabase $ZERO_OID 209 - test_atom tag '*deltabase' $ZERO_OID 210 - test_atom tag objectname $(git rev-parse refs/tags/testtag) 211 - test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag) 212 - test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) 213 - test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) 214 - test_atom tag tree '' 215 - test_atom tag tree:short '' 216 - test_atom tag tree:short=1 '' 217 - test_atom tag tree:short=10 '' 218 - test_atom tag parent '' 219 - test_atom tag parent:short '' 220 - test_atom tag parent:short=1 '' 221 - test_atom tag parent:short=10 '' 222 - test_atom tag numparent '' 223 - test_atom tag object $(git rev-parse refs/tags/testtag^0) 224 - test_atom tag type 'commit' 225 - test_atom tag '*objectname' $(git rev-parse refs/tags/testtag^{}) 226 - test_atom tag '*objecttype' 'commit' 227 - test_atom tag author '' 228 - test_atom tag authorname '' 229 - test_atom tag authorname:mailmap '' 230 - test_atom tag authoremail '' 231 - test_atom tag authoremail:trim '' 232 - test_atom tag authoremail:localpart '' 233 - test_atom tag authoremail:trim,localpart '' 234 - test_atom tag authoremail:mailmap '' 235 - test_atom tag authoremail:mailmap,trim '' 236 - test_atom tag authoremail:trim,mailmap '' 237 - test_atom tag authoremail:mailmap,localpart '' 238 - test_atom tag authoremail:localpart,mailmap '' 239 - test_atom tag authoremail:mailmap,trim,localpart,mailmap,trim '' 240 - test_atom tag authordate '' 241 - test_atom tag committer '' 242 - test_atom tag committername '' 243 - test_atom tag committername:mailmap '' 244 - test_atom tag committeremail '' 245 - test_atom tag committeremail:trim '' 246 - test_atom tag committeremail:localpart '' 247 - test_atom tag committeremail:localpart,trim '' 248 - test_atom tag committeremail:mailmap '' 249 - test_atom tag committeremail:mailmap,trim '' 250 - test_atom tag committeremail:trim,mailmap '' 251 - test_atom tag committeremail:mailmap,localpart '' 252 - test_atom tag committeremail:localpart,mailmap '' 253 - test_atom tag committeremail:trim,mailmap,trim,trim,localpart '' 254 - test_atom tag committerdate '' 255 - test_atom tag tag 'testtag' 256 - test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200' 257 - test_atom tag taggername 'C O Mitter' 258 - test_atom tag taggername:mailmap 'C Mitter' 259 - test_atom tag taggeremail '<committer@example.com>' 260 - test_atom tag taggeremail:trim 'committer@example.com' 261 - test_atom tag taggeremail:localpart 'committer' 262 - test_atom tag taggeremail:trim,localpart 'committer' 263 - test_atom tag taggeremail:mailmap '<cmitter@example.com>' 264 - test_atom tag taggeremail:mailmap,trim 'cmitter@example.com' 265 - test_atom tag taggeremail:trim,mailmap 'cmitter@example.com' 266 - test_atom tag taggeremail:mailmap,localpart 'cmitter' 267 - test_atom tag taggeremail:localpart,mailmap 'cmitter' 268 - test_atom tag taggeremail:trim,mailmap,trim,localpart,localpart 'cmitter' 269 - test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200' 270 - test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200' 271 - test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200' 272 - test_atom tag subject 'Tagging at 1151968727' 273 - test_atom tag subject:sanitize 'Tagging-at-1151968727' 274 - test_atom tag contents:subject 'Tagging at 1151968727' 275 - test_atom tag body '' 276 - test_atom tag contents:body '' 277 - test_atom tag contents:signature '' 278 - test_atom tag contents 'Tagging at 1151968727 279 - ' 280 - test_atom tag HEAD ' ' 281 - 282 - test_expect_success 'basic atom: refs/tags/testtag *raw' ' 283 - git cat-file commit refs/tags/testtag^{} >expected && 284 - git for-each-ref --format="%(*raw)" refs/tags/testtag >actual && 285 - sanitize_pgp <expected >expected.clean && 286 - echo >>expected.clean && 287 - sanitize_pgp <actual >actual.clean && 288 - test_cmp expected.clean actual.clean 289 - ' 290 - 291 - test_expect_success 'Check invalid atoms names are errors' ' 292 - test_must_fail git for-each-ref --format="%(INVALID)" refs/heads 293 - ' 294 - 295 - test_expect_success 'for-each-ref does not crash with -h' ' 10 + test_expect_success "for-each-ref does not crash with -h" ' 296 11 test_expect_code 129 git for-each-ref -h >usage && 297 12 test_grep "[Uu]sage: git for-each-ref " usage && 298 13 test_expect_code 129 nongit git for-each-ref -h >usage && 299 14 test_grep "[Uu]sage: git for-each-ref " usage 300 15 ' 301 16 302 - test_expect_success 'Check format specifiers are ignored in naming date atoms' ' 303 - git for-each-ref --format="%(authordate)" refs/heads && 304 - git for-each-ref --format="%(authordate:default) %(authordate)" refs/heads && 305 - git for-each-ref --format="%(authordate) %(authordate:default)" refs/heads && 306 - git for-each-ref --format="%(authordate:default) %(authordate:default)" refs/heads 307 - ' 308 - 309 - test_expect_success 'Check valid format specifiers for date fields' ' 310 - git for-each-ref --format="%(authordate:default)" refs/heads && 311 - git for-each-ref --format="%(authordate:relative)" refs/heads && 312 - git for-each-ref --format="%(authordate:short)" refs/heads && 313 - git for-each-ref --format="%(authordate:local)" refs/heads && 314 - git for-each-ref --format="%(authordate:iso8601)" refs/heads && 315 - git for-each-ref --format="%(authordate:rfc2822)" refs/heads 316 - ' 317 - 318 - test_expect_success 'Check invalid format specifiers are errors' ' 319 - test_must_fail git for-each-ref --format="%(authordate:INVALID)" refs/heads 320 - ' 321 - 322 - test_expect_success 'arguments to %(objectname:short=) must be positive integers' ' 323 - test_must_fail git for-each-ref --format="%(objectname:short=0)" && 324 - test_must_fail git for-each-ref --format="%(objectname:short=-1)" && 325 - test_must_fail git for-each-ref --format="%(objectname:short=foo)" 326 - ' 327 - 328 - test_bad_atom () { 329 - case "$1" in 330 - head) ref=refs/heads/main ;; 331 - tag) ref=refs/tags/testtag ;; 332 - sym) ref=refs/heads/sym ;; 333 - *) ref=$1 ;; 334 - esac 335 - format=$2 336 - test_do=test_expect_${4:-success} 337 - 338 - printf '%s\n' "$3" >expect 339 - $test_do $PREREQ "err basic atom: $ref $format" ' 340 - test_must_fail git for-each-ref \ 341 - --format="%($format)" "$ref" 2>error && 342 - test_cmp expect error 343 - ' 344 - } 345 - 346 - test_bad_atom head 'authoremail:foo' \ 347 - 'fatal: unrecognized %(authoremail) argument: foo' 348 - 349 - test_bad_atom head 'authoremail:mailmap,trim,bar' \ 350 - 'fatal: unrecognized %(authoremail) argument: bar' 351 - 352 - test_bad_atom head 'authoremail:trim,' \ 353 - 'fatal: unrecognized %(authoremail) argument: ' 354 - 355 - test_bad_atom head 'authoremail:mailmaptrim' \ 356 - 'fatal: unrecognized %(authoremail) argument: trim' 357 - 358 - test_bad_atom head 'committeremail: ' \ 359 - 'fatal: unrecognized %(committeremail) argument: ' 360 - 361 - test_bad_atom head 'committeremail: trim,foo' \ 362 - 'fatal: unrecognized %(committeremail) argument: trim,foo' 363 - 364 - test_bad_atom head 'committeremail:mailmap,localpart ' \ 365 - 'fatal: unrecognized %(committeremail) argument: ' 366 - 367 - test_bad_atom head 'committeremail:trim_localpart' \ 368 - 'fatal: unrecognized %(committeremail) argument: _localpart' 369 - 370 - test_bad_atom head 'committeremail:localpart,,,trim' \ 371 - 'fatal: unrecognized %(committeremail) argument: ,,trim' 372 - 373 - test_bad_atom tag 'taggeremail:mailmap,trim, foo ' \ 374 - 'fatal: unrecognized %(taggeremail) argument: foo ' 375 - 376 - test_bad_atom tag 'taggeremail:trim,localpart,' \ 377 - 'fatal: unrecognized %(taggeremail) argument: ' 378 - 379 - test_bad_atom tag 'taggeremail:mailmap;localpart trim' \ 380 - 'fatal: unrecognized %(taggeremail) argument: ;localpart trim' 381 - 382 - test_bad_atom tag 'taggeremail:localpart trim' \ 383 - 'fatal: unrecognized %(taggeremail) argument: trim' 384 - 385 - test_bad_atom tag 'taggeremail:mailmap,mailmap,trim,qux,localpart,trim' \ 386 - 'fatal: unrecognized %(taggeremail) argument: qux,localpart,trim' 387 - 388 - test_date () { 389 - f=$1 && 390 - committer_date=$2 && 391 - author_date=$3 && 392 - tagger_date=$4 && 393 - cat >expected <<-EOF && 394 - 'refs/heads/main' '$committer_date' '$author_date' 395 - 'refs/tags/testtag' '$tagger_date' 396 - EOF 397 - ( 398 - git for-each-ref --shell \ 399 - --format="%(refname) %(committerdate${f:+:$f}) %(authordate${f:+:$f})" \ 400 - refs/heads && 401 - git for-each-ref --shell \ 402 - --format="%(refname) %(taggerdate${f:+:$f})" \ 403 - refs/tags 404 - ) >actual && 405 - test_cmp expected actual 406 - } 407 - 408 - test_expect_success 'Check unformatted date fields output' ' 409 - test_date "" \ 410 - "Tue Jul 4 01:18:43 2006 +0200" \ 411 - "Tue Jul 4 01:18:44 2006 +0200" \ 412 - "Tue Jul 4 01:18:45 2006 +0200" 413 - ' 414 - 415 - test_expect_success 'Check format "default" formatted date fields output' ' 416 - test_date default \ 417 - "Tue Jul 4 01:18:43 2006 +0200" \ 418 - "Tue Jul 4 01:18:44 2006 +0200" \ 419 - "Tue Jul 4 01:18:45 2006 +0200" 420 - ' 421 - 422 - test_expect_success 'Check format "default-local" date fields output' ' 423 - test_date default-local "Mon Jul 3 23:18:43 2006" "Mon Jul 3 23:18:44 2006" "Mon Jul 3 23:18:45 2006" 424 - ' 425 - 426 - # Don't know how to do relative check because I can't know when this script 427 - # is going to be run and can't fake the current time to git, and hence can't 428 - # provide expected output. Instead, I'll just make sure that "relative" 429 - # doesn't exit in error 430 - test_expect_success 'Check format "relative" date fields output' ' 431 - f=relative && 432 - (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && 433 - git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual 434 - ' 435 - 436 - # We just check that this is the same as "relative" for now. 437 - test_expect_success 'Check format "relative-local" date fields output' ' 438 - test_date relative-local \ 439 - "$(git for-each-ref --format="%(committerdate:relative)" refs/heads)" \ 440 - "$(git for-each-ref --format="%(authordate:relative)" refs/heads)" \ 441 - "$(git for-each-ref --format="%(taggerdate:relative)" refs/tags)" 442 - ' 443 - 444 - test_expect_success 'Check format "short" date fields output' ' 445 - test_date short 2006-07-04 2006-07-04 2006-07-04 446 - ' 447 - 448 - test_expect_success 'Check format "short-local" date fields output' ' 449 - test_date short-local 2006-07-03 2006-07-03 2006-07-03 450 - ' 451 - 452 - test_expect_success 'Check format "local" date fields output' ' 453 - test_date local \ 454 - "Mon Jul 3 23:18:43 2006" \ 455 - "Mon Jul 3 23:18:44 2006" \ 456 - "Mon Jul 3 23:18:45 2006" 457 - ' 458 - 459 - test_expect_success 'Check format "iso8601" date fields output' ' 460 - test_date iso8601 \ 461 - "2006-07-04 01:18:43 +0200" \ 462 - "2006-07-04 01:18:44 +0200" \ 463 - "2006-07-04 01:18:45 +0200" 464 - ' 465 - 466 - test_expect_success 'Check format "iso8601-local" date fields output' ' 467 - test_date iso8601-local "2006-07-03 23:18:43 +0000" "2006-07-03 23:18:44 +0000" "2006-07-03 23:18:45 +0000" 468 - ' 469 - 470 - test_expect_success 'Check format "rfc2822" date fields output' ' 471 - test_date rfc2822 \ 472 - "Tue, 4 Jul 2006 01:18:43 +0200" \ 473 - "Tue, 4 Jul 2006 01:18:44 +0200" \ 474 - "Tue, 4 Jul 2006 01:18:45 +0200" 475 - ' 476 - 477 - test_expect_success 'Check format "rfc2822-local" date fields output' ' 478 - test_date rfc2822-local "Mon, 3 Jul 2006 23:18:43 +0000" "Mon, 3 Jul 2006 23:18:44 +0000" "Mon, 3 Jul 2006 23:18:45 +0000" 479 - ' 480 - 481 - test_expect_success 'Check format "raw" date fields output' ' 482 - test_date raw "1151968723 +0200" "1151968724 +0200" "1151968725 +0200" 483 - ' 484 - 485 - test_expect_success 'Check format "raw-local" date fields output' ' 486 - test_date raw-local "1151968723 +0000" "1151968724 +0000" "1151968725 +0000" 487 - ' 488 - 489 - test_expect_success 'Check format of strftime date fields' ' 490 - echo "my date is 2006-07-04" >expected && 491 - git for-each-ref \ 492 - --format="%(authordate:format:my date is %Y-%m-%d)" \ 493 - refs/heads >actual && 494 - test_cmp expected actual 495 - ' 496 - 497 - test_expect_success 'Check format of strftime-local date fields' ' 498 - echo "my date is 2006-07-03" >expected && 499 - git for-each-ref \ 500 - --format="%(authordate:format-local:my date is %Y-%m-%d)" \ 501 - refs/heads >actual && 502 - test_cmp expected actual 503 - ' 504 - 505 - test_expect_success 'exercise strftime with odd fields' ' 506 - echo >expected && 507 - git for-each-ref --format="%(authordate:format:)" refs/heads >actual && 508 - test_cmp expected actual && 509 - long="long format -- $ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID" && 510 - echo $long >expected && 511 - git for-each-ref --format="%(authordate:format:$long)" refs/heads >actual && 512 - test_cmp expected actual 513 - ' 514 - 515 - cat >expected <<\EOF 516 - refs/heads/main 517 - refs/remotes/origin/main 518 - refs/tags/testtag 519 - EOF 520 - 521 - test_expect_success 'Verify ascending sort' ' 522 - git for-each-ref --format="%(refname)" --sort=refname >actual && 523 - test_cmp expected actual 524 - ' 525 - 526 - 527 - cat >expected <<\EOF 528 - refs/tags/testtag 529 - refs/remotes/origin/main 530 - refs/heads/main 531 - EOF 532 - 533 - test_expect_success 'Verify descending sort' ' 534 - git for-each-ref --format="%(refname)" --sort=-refname >actual && 535 - test_cmp expected actual 536 - ' 537 - 538 - test_expect_success 'Give help even with invalid sort atoms' ' 539 - test_expect_code 129 git for-each-ref --sort=bogus -h >actual 2>&1 && 540 - grep "^usage: git for-each-ref" actual 541 - ' 542 - 543 - cat >expected <<\EOF 544 - refs/tags/testtag 545 - refs/tags/testtag-2 546 - EOF 547 - 548 - test_expect_success 'exercise patterns with prefixes' ' 549 - git tag testtag-2 && 550 - test_when_finished "git tag -d testtag-2" && 551 - git for-each-ref --format="%(refname)" \ 552 - refs/tags/testtag refs/tags/testtag-2 >actual && 553 - test_cmp expected actual 554 - ' 555 - 556 - cat >expected <<\EOF 557 - refs/tags/testtag 558 - refs/tags/testtag-2 559 - EOF 560 - 561 - test_expect_success 'exercise glob patterns with prefixes' ' 562 - git tag testtag-2 && 563 - test_when_finished "git tag -d testtag-2" && 564 - git for-each-ref --format="%(refname)" \ 565 - refs/tags/testtag "refs/tags/testtag-*" >actual && 566 - test_cmp expected actual 567 - ' 568 - 569 - cat >expected <<\EOF 570 - refs/tags/bar 571 - refs/tags/baz 572 - refs/tags/testtag 573 - EOF 574 - 575 - test_expect_success 'exercise patterns with prefix exclusions' ' 576 - for tag in foo/one foo/two foo/three bar baz 577 - do 578 - git tag "$tag" || return 1 579 - done && 580 - test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && 581 - git for-each-ref --format="%(refname)" \ 582 - refs/tags/ --exclude=refs/tags/foo >actual && 583 - test_cmp expected actual 584 - ' 585 - 586 - cat >expected <<\EOF 587 - refs/tags/bar 588 - refs/tags/baz 589 - refs/tags/foo/one 590 - refs/tags/testtag 591 - EOF 592 - 593 - test_expect_success 'exercise patterns with pattern exclusions' ' 594 - for tag in foo/one foo/two foo/three bar baz 595 - do 596 - git tag "$tag" || return 1 597 - done && 598 - test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && 599 - git for-each-ref --format="%(refname)" \ 600 - refs/tags/ --exclude="refs/tags/foo/t*" >actual && 601 - test_cmp expected actual 602 - ' 603 - 604 - cat >expected <<\EOF 605 - 'refs/heads/main' 606 - 'refs/remotes/origin/main' 607 - 'refs/tags/testtag' 608 - EOF 609 - 610 - test_expect_success 'Quoting style: shell' ' 611 - git for-each-ref --shell --format="%(refname)" >actual && 612 - test_cmp expected actual 613 - ' 614 - 615 - test_expect_success 'Quoting style: perl' ' 616 - git for-each-ref --perl --format="%(refname)" >actual && 617 - test_cmp expected actual 618 - ' 619 - 620 - test_expect_success 'Quoting style: python' ' 621 - git for-each-ref --python --format="%(refname)" >actual && 622 - test_cmp expected actual 623 - ' 624 - 625 - cat >expected <<\EOF 626 - "refs/heads/main" 627 - "refs/remotes/origin/main" 628 - "refs/tags/testtag" 629 - EOF 630 - 631 - test_expect_success 'Quoting style: tcl' ' 632 - git for-each-ref --tcl --format="%(refname)" >actual && 633 - test_cmp expected actual 634 - ' 635 - 636 - for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do 637 - test_expect_success "more than one quoting style: $i" " 638 - test_must_fail git for-each-ref $i 2>err && 639 - grep '^error: more than one quoting style' err 640 - " 641 - done 642 - 643 - test_expect_success 'setup for upstream:track[short]' ' 644 - test_commit two 645 - ' 646 - 647 - test_atom head upstream:track '[ahead 1]' 648 - test_atom head upstream:trackshort '>' 649 - test_atom head upstream:track,nobracket 'ahead 1' 650 - test_atom head upstream:nobracket,track 'ahead 1' 651 - 652 - test_expect_success 'setup for push:track[short]' ' 653 - test_commit third && 654 - git update-ref refs/remotes/myfork/main main && 655 - git reset main~1 656 - ' 657 - 658 - test_atom head push:track '[behind 1]' 659 - test_atom head push:trackshort '<' 660 - 661 - test_expect_success 'Check that :track[short] cannot be used with other atoms' ' 662 - test_must_fail git for-each-ref --format="%(refname:track)" 2>/dev/null && 663 - test_must_fail git for-each-ref --format="%(refname:trackshort)" 2>/dev/null 664 - ' 665 - 666 - test_expect_success 'Check that :track[short] works when upstream is invalid' ' 667 - cat >expected <<-\EOF && 668 - [gone] 669 - 670 - EOF 671 - test_when_finished "git config branch.main.merge refs/heads/main" && 672 - git config branch.main.merge refs/heads/does-not-exist && 673 - git for-each-ref \ 674 - --format="%(upstream:track)$LF%(upstream:trackshort)" \ 675 - refs/heads >actual && 676 - test_cmp expected actual 677 - ' 678 - 679 - test_expect_success 'Check for invalid refname format' ' 680 - test_must_fail git for-each-ref --format="%(refname:INVALID)" 681 - ' 682 - 683 - test_expect_success 'set up color tests' ' 684 - cat >expected.color <<-EOF && 685 - $(git rev-parse --short refs/heads/main) <GREEN>main<RESET> 686 - $(git rev-parse --short refs/remotes/myfork/main) <GREEN>myfork/main<RESET> 687 - $(git rev-parse --short refs/remotes/origin/main) <GREEN>origin/main<RESET> 688 - $(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET> 689 - $(git rev-parse --short refs/tags/third) <GREEN>third<RESET> 690 - $(git rev-parse --short refs/tags/two) <GREEN>two<RESET> 691 - EOF 692 - sed "s/<[^>]*>//g" <expected.color >expected.bare && 693 - color_format="%(objectname:short) %(color:green)%(refname:short)" 694 - ' 695 - 696 - test_expect_success TTY '%(color) shows color with a tty' ' 697 - test_terminal git for-each-ref --format="$color_format" >actual.raw && 698 - test_decode_color <actual.raw >actual && 699 - test_cmp expected.color actual 700 - ' 701 - 702 - test_expect_success '%(color) does not show color without tty' ' 703 - TERM=vt100 git for-each-ref --format="$color_format" >actual && 704 - test_cmp expected.bare actual 705 - ' 706 - 707 - test_expect_success '--color can override tty check' ' 708 - git for-each-ref --color --format="$color_format" >actual.raw && 709 - test_decode_color <actual.raw >actual && 710 - test_cmp expected.color actual 711 - ' 712 - 713 - test_expect_success 'color.ui=always does not override tty check' ' 714 - git -c color.ui=always for-each-ref --format="$color_format" >actual && 715 - test_cmp expected.bare actual 716 - ' 717 - 718 - test_expect_success 'setup for describe atom tests' ' 719 - git init -b master describe-repo && 720 - ( 721 - cd describe-repo && 722 - 723 - test_commit --no-tag one && 724 - git tag tagone && 725 - 726 - test_commit --no-tag two && 727 - git tag -a -m "tag two" tagtwo 728 - ) 729 - ' 730 - 731 - test_expect_success 'describe atom vs git describe' ' 732 - ( 733 - cd describe-repo && 734 - 735 - git for-each-ref --format="%(objectname)" \ 736 - refs/tags/ >obj && 737 - while read hash 738 - do 739 - if desc=$(git describe $hash) 740 - then 741 - : >expect-contains-good 742 - else 743 - : >expect-contains-bad 744 - fi && 745 - echo "$hash $desc" || return 1 746 - done <obj >expect && 747 - test_path_exists expect-contains-good && 748 - test_path_exists expect-contains-bad && 749 - 750 - git for-each-ref --format="%(objectname) %(describe)" \ 751 - refs/tags/ >actual 2>err && 752 - test_cmp expect actual && 753 - test_must_be_empty err 754 - ) 755 - ' 756 - 757 - test_expect_success 'describe:tags vs describe --tags' ' 758 - ( 759 - cd describe-repo && 760 - git describe --tags >expect && 761 - git for-each-ref --format="%(describe:tags)" \ 762 - refs/heads/master >actual && 763 - test_cmp expect actual 764 - ) 765 - ' 766 - 767 - test_expect_success 'describe:abbrev=... vs describe --abbrev=...' ' 768 - ( 769 - cd describe-repo && 770 - 771 - # Case 1: We have commits between HEAD and the most 772 - # recent tag reachable from it 773 - test_commit --no-tag file && 774 - git describe --abbrev=14 >expect && 775 - git for-each-ref --format="%(describe:abbrev=14)" \ 776 - refs/heads/master >actual && 777 - test_cmp expect actual && 778 - 779 - # Make sure the hash used is at least 14 digits long 780 - sed -e "s/^.*-g\([0-9a-f]*\)$/\1/" <actual >hexpart && 781 - test 15 -le $(wc -c <hexpart) && 782 - 783 - # Case 2: We have a tag at HEAD, describe directly gives 784 - # the name of the tag 785 - git tag -a -m tagged tagname && 786 - git describe --abbrev=14 >expect && 787 - git for-each-ref --format="%(describe:abbrev=14)" \ 788 - refs/heads/master >actual && 789 - test_cmp expect actual && 790 - test tagname = $(cat actual) 791 - ) 792 - ' 793 - 794 - test_expect_success 'describe:match=... vs describe --match ...' ' 795 - ( 796 - cd describe-repo && 797 - git tag -a -m "tag foo" tag-foo && 798 - git describe --match "*-foo" >expect && 799 - git for-each-ref --format="%(describe:match="*-foo")" \ 800 - refs/heads/master >actual && 801 - test_cmp expect actual 802 - ) 803 - ' 804 - 805 - test_expect_success 'describe:exclude:... vs describe --exclude ...' ' 806 - ( 807 - cd describe-repo && 808 - git tag -a -m "tag bar" tag-bar && 809 - git describe --exclude "*-bar" >expect && 810 - git for-each-ref --format="%(describe:exclude="*-bar")" \ 811 - refs/heads/master >actual && 812 - test_cmp expect actual 813 - ) 814 - ' 815 - 816 - test_expect_success 'deref with describe atom' ' 817 - ( 818 - cd describe-repo && 819 - cat >expect <<-\EOF && 820 - 821 - tagname 822 - tagname 823 - tagname 824 - 825 - tagtwo 826 - EOF 827 - git for-each-ref --format="%(*describe)" >actual && 828 - test_cmp expect actual 829 - ) 830 - ' 831 - 832 - test_expect_success 'err on bad describe atom arg' ' 833 - ( 834 - cd describe-repo && 835 - 836 - # The bad arg is the only arg passed to describe atom 837 - cat >expect <<-\EOF && 838 - fatal: unrecognized %(describe) argument: baz 839 - EOF 840 - test_must_fail git for-each-ref --format="%(describe:baz)" \ 841 - refs/heads/master 2>actual && 842 - test_cmp expect actual && 843 - 844 - # The bad arg is in the middle of the option string 845 - # passed to the describe atom 846 - cat >expect <<-\EOF && 847 - fatal: unrecognized %(describe) argument: qux=1,abbrev=14 848 - EOF 849 - test_must_fail git for-each-ref \ 850 - --format="%(describe:tags,qux=1,abbrev=14)" \ 851 - ref/heads/master 2>actual && 852 - test_cmp expect actual 853 - ) 854 - ' 855 - 856 - cat >expected <<\EOF 857 - heads/main 858 - tags/main 859 - EOF 860 - 861 - test_expect_success 'Check ambiguous head and tag refs (strict)' ' 862 - git config --bool core.warnambiguousrefs true && 863 - git checkout -b newtag && 864 - echo "Using $datestamp" > one && 865 - git add one && 866 - git commit -m "Branch" && 867 - setdate_and_increment && 868 - git tag -m "Tagging at $datestamp" main && 869 - git for-each-ref --format "%(refname:short)" refs/heads/main refs/tags/main >actual && 870 - test_cmp expected actual 871 - ' 872 - 873 - cat >expected <<\EOF 874 - heads/main 875 - main 876 - EOF 877 - 878 - test_expect_success 'Check ambiguous head and tag refs (loose)' ' 879 - git config --bool core.warnambiguousrefs false && 880 - git for-each-ref --format "%(refname:short)" refs/heads/main refs/tags/main >actual && 881 - test_cmp expected actual 882 - ' 883 - 884 - cat >expected <<\EOF 885 - heads/ambiguous 886 - ambiguous 887 - EOF 888 - 889 - test_expect_success 'Check ambiguous head and tag refs II (loose)' ' 890 - git checkout main && 891 - git tag ambiguous testtag^0 && 892 - git branch ambiguous testtag^0 && 893 - git for-each-ref --format "%(refname:short)" refs/heads/ambiguous refs/tags/ambiguous >actual && 894 - test_cmp expected actual 895 - ' 896 - 897 - test_expect_success 'create tag without tagger' ' 898 - git tag -a -m "Broken tag" taggerless && 899 - git tag -f taggerless $(git cat-file tag taggerless | 900 - sed -e "/^tagger /d" | 901 - git hash-object --literally --stdin -w -t tag) 902 - ' 903 - 904 - test_atom refs/tags/taggerless type 'commit' 905 - test_atom refs/tags/taggerless tag 'taggerless' 906 - test_atom refs/tags/taggerless tagger '' 907 - test_atom refs/tags/taggerless taggername '' 908 - test_atom refs/tags/taggerless taggeremail '' 909 - test_atom refs/tags/taggerless taggeremail:trim '' 910 - test_atom refs/tags/taggerless taggeremail:localpart '' 911 - test_atom refs/tags/taggerless taggerdate '' 912 - test_atom refs/tags/taggerless committer '' 913 - test_atom refs/tags/taggerless committername '' 914 - test_atom refs/tags/taggerless committeremail '' 915 - test_atom refs/tags/taggerless committeremail:trim '' 916 - test_atom refs/tags/taggerless committeremail:localpart '' 917 - test_atom refs/tags/taggerless committerdate '' 918 - test_atom refs/tags/taggerless subject 'Broken tag' 919 - 920 - test_expect_success 'an unusual tag with an incomplete line' ' 921 - 922 - git tag -m "bogo" bogo && 923 - bogo=$(git cat-file tag bogo) && 924 - bogo=$(printf "%s" "$bogo" | git mktag) && 925 - git tag -f bogo "$bogo" && 926 - git for-each-ref --format "%(body)" refs/tags/bogo 927 - 928 - ' 929 - 930 - test_expect_success 'create tag with subject and body content' ' 931 - cat >>msg <<-\EOF && 932 - the subject line 933 - 934 - first body line 935 - second body line 936 - EOF 937 - git tag -F msg subject-body 938 - ' 939 - test_atom refs/tags/subject-body subject 'the subject line' 940 - test_atom refs/tags/subject-body subject:sanitize 'the-subject-line' 941 - test_atom refs/tags/subject-body body 'first body line 942 - second body line 943 - ' 944 - test_atom refs/tags/subject-body contents 'the subject line 945 - 946 - first body line 947 - second body line 948 - ' 949 - 950 - test_expect_success 'create tag with multiline subject' ' 951 - cat >msg <<-\EOF && 952 - first subject line 953 - second subject line 954 - 955 - first body line 956 - second body line 957 - EOF 958 - git tag -F msg multiline 959 - ' 960 - test_atom refs/tags/multiline subject 'first subject line second subject line' 961 - test_atom refs/tags/multiline subject:sanitize 'first-subject-line-second-subject-line' 962 - test_atom refs/tags/multiline contents:subject 'first subject line second subject line' 963 - test_atom refs/tags/multiline body 'first body line 964 - second body line 965 - ' 966 - test_atom refs/tags/multiline contents:body 'first body line 967 - second body line 968 - ' 969 - test_atom refs/tags/multiline contents:signature '' 970 - test_atom refs/tags/multiline contents 'first subject line 971 - second subject line 972 - 973 - first body line 974 - second body line 975 - ' 976 - 977 - test_expect_success GPG 'create signed tags' ' 978 - git tag -s -m "" signed-empty && 979 - git tag -s -m "subject line" signed-short && 980 - cat >msg <<-\EOF && 981 - subject line 982 - 983 - body contents 984 - EOF 985 - git tag -s -F msg signed-long 986 - ' 987 - 988 - sig='-----BEGIN PGP SIGNATURE----- 989 - -----END PGP SIGNATURE----- 990 - ' 991 - 992 - PREREQ=GPG 993 - test_atom refs/tags/signed-empty subject '' 994 - test_atom refs/tags/signed-empty subject:sanitize '' 995 - test_atom refs/tags/signed-empty contents:subject '' 996 - test_atom refs/tags/signed-empty body "$sig" 997 - test_atom refs/tags/signed-empty contents:body '' 998 - test_atom refs/tags/signed-empty contents:signature "$sig" 999 - test_atom refs/tags/signed-empty contents "$sig" 1000 - 1001 - test_expect_success GPG 'basic atom: refs/tags/signed-empty raw' ' 1002 - git cat-file tag refs/tags/signed-empty >expected && 1003 - git for-each-ref --format="%(raw)" refs/tags/signed-empty >actual && 1004 - sanitize_pgp <expected >expected.clean && 1005 - echo >>expected.clean && 1006 - sanitize_pgp <actual >actual.clean && 1007 - test_cmp expected.clean actual.clean 1008 - ' 1009 - 1010 - test_atom refs/tags/signed-short subject 'subject line' 1011 - test_atom refs/tags/signed-short subject:sanitize 'subject-line' 1012 - test_atom refs/tags/signed-short contents:subject 'subject line' 1013 - test_atom refs/tags/signed-short body "$sig" 1014 - test_atom refs/tags/signed-short contents:body '' 1015 - test_atom refs/tags/signed-short contents:signature "$sig" 1016 - test_atom refs/tags/signed-short contents "subject line 1017 - $sig" 1018 - 1019 - test_expect_success GPG 'basic atom: refs/tags/signed-short raw' ' 1020 - git cat-file tag refs/tags/signed-short >expected && 1021 - git for-each-ref --format="%(raw)" refs/tags/signed-short >actual && 1022 - sanitize_pgp <expected >expected.clean && 1023 - echo >>expected.clean && 1024 - sanitize_pgp <actual >actual.clean && 1025 - test_cmp expected.clean actual.clean 1026 - ' 1027 - 1028 - test_atom refs/tags/signed-long subject 'subject line' 1029 - test_atom refs/tags/signed-long subject:sanitize 'subject-line' 1030 - test_atom refs/tags/signed-long contents:subject 'subject line' 1031 - test_atom refs/tags/signed-long body "body contents 1032 - $sig" 1033 - test_atom refs/tags/signed-long contents:body 'body contents 1034 - ' 1035 - test_atom refs/tags/signed-long contents:signature "$sig" 1036 - test_atom refs/tags/signed-long contents "subject line 1037 - 1038 - body contents 1039 - $sig" 1040 - 1041 - test_expect_success GPG 'basic atom: refs/tags/signed-long raw' ' 1042 - git cat-file tag refs/tags/signed-long >expected && 1043 - git for-each-ref --format="%(raw)" refs/tags/signed-long >actual && 1044 - sanitize_pgp <expected >expected.clean && 1045 - echo >>expected.clean && 1046 - sanitize_pgp <actual >actual.clean && 1047 - test_cmp expected.clean actual.clean 1048 - ' 1049 - 1050 - test_expect_success 'set up refs pointing to tree and blob' ' 1051 - git update-ref refs/mytrees/first refs/heads/main^{tree} && 1052 - git update-ref refs/myblobs/first refs/heads/main:one 1053 - ' 1054 - 1055 - test_atom refs/mytrees/first subject "" 1056 - test_atom refs/mytrees/first contents:subject "" 1057 - test_atom refs/mytrees/first body "" 1058 - test_atom refs/mytrees/first contents:body "" 1059 - test_atom refs/mytrees/first contents:signature "" 1060 - test_atom refs/mytrees/first contents "" 1061 - 1062 - test_expect_success 'basic atom: refs/mytrees/first raw' ' 1063 - git cat-file tree refs/mytrees/first >expected && 1064 - echo >>expected && 1065 - git for-each-ref --format="%(raw)" refs/mytrees/first >actual && 1066 - test_cmp expected actual && 1067 - git cat-file -s refs/mytrees/first >expected && 1068 - git for-each-ref --format="%(raw:size)" refs/mytrees/first >actual && 1069 - test_cmp expected actual 1070 - ' 1071 - 1072 - test_atom refs/myblobs/first subject "" 1073 - test_atom refs/myblobs/first contents:subject "" 1074 - test_atom refs/myblobs/first body "" 1075 - test_atom refs/myblobs/first contents:body "" 1076 - test_atom refs/myblobs/first contents:signature "" 1077 - test_atom refs/myblobs/first contents "" 1078 - 1079 - test_expect_success 'basic atom: refs/myblobs/first raw' ' 1080 - git cat-file blob refs/myblobs/first >expected && 1081 - echo >>expected && 1082 - git for-each-ref --format="%(raw)" refs/myblobs/first >actual && 1083 - test_cmp expected actual && 1084 - git cat-file -s refs/myblobs/first >expected && 1085 - git for-each-ref --format="%(raw:size)" refs/myblobs/first >actual && 1086 - test_cmp expected actual 1087 - ' 1088 - 1089 - test_expect_success 'set up refs pointing to binary blob' ' 1090 - printf "a\0b\0c" >blob1 && 1091 - printf "a\0c\0b" >blob2 && 1092 - printf "\0a\0b\0c" >blob3 && 1093 - printf "abc" >blob4 && 1094 - printf "\0 \0 \0 " >blob5 && 1095 - printf "\0 \0a\0 " >blob6 && 1096 - printf " " >blob7 && 1097 - >blob8 && 1098 - obj=$(git hash-object -w blob1) && 1099 - git update-ref refs/myblobs/blob1 "$obj" && 1100 - obj=$(git hash-object -w blob2) && 1101 - git update-ref refs/myblobs/blob2 "$obj" && 1102 - obj=$(git hash-object -w blob3) && 1103 - git update-ref refs/myblobs/blob3 "$obj" && 1104 - obj=$(git hash-object -w blob4) && 1105 - git update-ref refs/myblobs/blob4 "$obj" && 1106 - obj=$(git hash-object -w blob5) && 1107 - git update-ref refs/myblobs/blob5 "$obj" && 1108 - obj=$(git hash-object -w blob6) && 1109 - git update-ref refs/myblobs/blob6 "$obj" && 1110 - obj=$(git hash-object -w blob7) && 1111 - git update-ref refs/myblobs/blob7 "$obj" && 1112 - obj=$(git hash-object -w blob8) && 1113 - git update-ref refs/myblobs/blob8 "$obj" 1114 - ' 1115 - 1116 - test_expect_success 'Verify sorts with raw' ' 1117 - cat >expected <<-EOF && 1118 - refs/myblobs/blob8 1119 - refs/myblobs/blob5 1120 - refs/myblobs/blob6 1121 - refs/myblobs/blob3 1122 - refs/myblobs/blob7 1123 - refs/mytrees/first 1124 - refs/myblobs/first 1125 - refs/myblobs/blob1 1126 - refs/myblobs/blob2 1127 - refs/myblobs/blob4 1128 - refs/heads/main 1129 - EOF 1130 - git for-each-ref --format="%(refname)" --sort=raw \ 1131 - refs/heads/main refs/myblobs/ refs/mytrees/first >actual && 1132 - test_cmp expected actual 1133 - ' 1134 - 1135 - test_expect_success 'Verify sorts with raw:size' ' 1136 - cat >expected <<-EOF && 1137 - refs/myblobs/blob8 1138 - refs/myblobs/blob7 1139 - refs/myblobs/blob4 1140 - refs/myblobs/blob1 1141 - refs/myblobs/blob2 1142 - refs/myblobs/blob3 1143 - refs/myblobs/blob5 1144 - refs/myblobs/blob6 1145 - refs/myblobs/first 1146 - refs/mytrees/first 1147 - refs/heads/main 1148 - EOF 1149 - git for-each-ref --format="%(refname)" --sort=raw:size \ 1150 - refs/heads/main refs/myblobs/ refs/mytrees/first >actual && 1151 - test_cmp expected actual 1152 - ' 1153 - 1154 - test_expect_success 'validate raw atom with %(if:equals)' ' 1155 - cat >expected <<-EOF && 1156 - not equals 1157 - not equals 1158 - not equals 1159 - not equals 1160 - not equals 1161 - not equals 1162 - refs/myblobs/blob4 1163 - not equals 1164 - not equals 1165 - not equals 1166 - not equals 1167 - not equals 1168 - EOF 1169 - git for-each-ref --format="%(if:equals=abc)%(raw)%(then)%(refname)%(else)not equals%(end)" \ 1170 - refs/myblobs/ refs/heads/ >actual && 1171 - test_cmp expected actual 1172 - ' 1173 - 1174 - test_expect_success 'validate raw atom with %(if:notequals)' ' 1175 - cat >expected <<-EOF && 1176 - refs/heads/ambiguous 1177 - refs/heads/main 1178 - refs/heads/newtag 1179 - refs/myblobs/blob1 1180 - refs/myblobs/blob2 1181 - refs/myblobs/blob3 1182 - equals 1183 - refs/myblobs/blob5 1184 - refs/myblobs/blob6 1185 - refs/myblobs/blob7 1186 - refs/myblobs/blob8 1187 - refs/myblobs/first 1188 - EOF 1189 - git for-each-ref --format="%(if:notequals=abc)%(raw)%(then)%(refname)%(else)equals%(end)" \ 1190 - refs/myblobs/ refs/heads/ >actual && 1191 - test_cmp expected actual 1192 - ' 1193 - 1194 - test_expect_success 'empty raw refs with %(if)' ' 1195 - cat >expected <<-EOF && 1196 - refs/myblobs/blob1 not empty 1197 - refs/myblobs/blob2 not empty 1198 - refs/myblobs/blob3 not empty 1199 - refs/myblobs/blob4 not empty 1200 - refs/myblobs/blob5 not empty 1201 - refs/myblobs/blob6 not empty 1202 - refs/myblobs/blob7 empty 1203 - refs/myblobs/blob8 empty 1204 - refs/myblobs/first not empty 1205 - EOF 1206 - git for-each-ref --format="%(refname) %(if)%(raw)%(then)not empty%(else)empty%(end)" \ 1207 - refs/myblobs/ >actual && 1208 - test_cmp expected actual 1209 - ' 1210 - 1211 - test_expect_success '%(raw) with --python must fail' ' 1212 - test_must_fail git for-each-ref --format="%(raw)" --python 1213 - ' 1214 - 1215 - test_expect_success '%(raw) with --tcl must fail' ' 1216 - test_must_fail git for-each-ref --format="%(raw)" --tcl 1217 - ' 1218 - 1219 - test_expect_success PERL_TEST_HELPERS '%(raw) with --perl' ' 1220 - git for-each-ref --format="\$name= %(raw); 1221 - print \"\$name\"" refs/myblobs/blob1 --perl | perl >actual && 1222 - cmp blob1 actual && 1223 - git for-each-ref --format="\$name= %(raw); 1224 - print \"\$name\"" refs/myblobs/blob3 --perl | perl >actual && 1225 - cmp blob3 actual && 1226 - git for-each-ref --format="\$name= %(raw); 1227 - print \"\$name\"" refs/myblobs/blob8 --perl | perl >actual && 1228 - cmp blob8 actual && 1229 - git for-each-ref --format="\$name= %(raw); 1230 - print \"\$name\"" refs/myblobs/first --perl | perl >actual && 1231 - cmp one actual && 1232 - git cat-file tree refs/mytrees/first > expected && 1233 - git for-each-ref --format="\$name= %(raw); 1234 - print \"\$name\"" refs/mytrees/first --perl | perl >actual && 1235 - cmp expected actual 1236 - ' 1237 - 1238 - test_expect_success '%(raw) with --shell must fail' ' 1239 - test_must_fail git for-each-ref --format="%(raw)" --shell 1240 - ' 1241 - 1242 - test_expect_success '%(raw) with --shell and --sort=raw must fail' ' 1243 - test_must_fail git for-each-ref --format="%(raw)" --sort=raw --shell 1244 - ' 1245 - 1246 - test_expect_success '%(raw:size) with --shell' ' 1247 - git for-each-ref --format="%(raw:size)" | sed "s/^/$SQ/;s/$/$SQ/" >expect && 1248 - git for-each-ref --format="%(raw:size)" --shell >actual && 1249 - test_cmp expect actual 1250 - ' 1251 - 1252 - test_expect_success 'for-each-ref --format compare with cat-file --batch' ' 1253 - git rev-parse refs/mytrees/first | git cat-file --batch >expected && 1254 - git for-each-ref --format="%(objectname) %(objecttype) %(objectsize) 1255 - %(raw)" refs/mytrees/first >actual && 1256 - test_cmp expected actual 1257 - ' 1258 - 1259 - test_expect_success 'verify sorts with contents:size' ' 1260 - cat >expect <<-\EOF && 1261 - refs/heads/main 1262 - refs/heads/newtag 1263 - refs/heads/ambiguous 1264 - EOF 1265 - git for-each-ref --format="%(refname)" \ 1266 - --sort=contents:size refs/heads/ >actual && 1267 - test_cmp expect actual 1268 - ' 1269 - 1270 - test_expect_success 'set up multiple-sort tags' ' 1271 - for when in 100000 200000 1272 - do 1273 - for email in user1 user2 1274 - do 1275 - for ref in ref1 ref2 1276 - do 1277 - GIT_COMMITTER_DATE="@$when +0000" \ 1278 - GIT_COMMITTER_EMAIL="$email@example.com" \ 1279 - git tag -m "tag $ref-$when-$email" \ 1280 - multi-$ref-$when-$email || return 1 1281 - done 1282 - done 1283 - done 1284 - ' 1285 - 1286 - test_expect_success 'Verify sort with multiple keys' ' 1287 - cat >expected <<-\EOF && 1288 - 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 1289 - 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 1290 - 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 1291 - 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 1292 - 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 1293 - 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 1294 - 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 1295 - 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 1296 - EOF 1297 - git for-each-ref \ 1298 - --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ 1299 - --sort=-refname \ 1300 - --sort=taggeremail \ 1301 - --sort=taggerdate \ 1302 - "refs/tags/multi-*" >actual && 1303 - test_cmp expected actual 1304 - ' 1305 - 1306 - test_expect_success 'equivalent sorts fall back on refname' ' 1307 - cat >expected <<-\EOF && 1308 - 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 1309 - 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 1310 - 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 1311 - 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 1312 - 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 1313 - 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 1314 - 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 1315 - 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 1316 - EOF 1317 - git for-each-ref \ 1318 - --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ 1319 - --sort=taggerdate \ 1320 - "refs/tags/multi-*" >actual && 1321 - test_cmp expected actual 1322 - ' 1323 - 1324 - test_expect_success '--no-sort cancels the previous sort keys' ' 1325 - cat >expected <<-\EOF && 1326 - 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 1327 - 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 1328 - 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 1329 - 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 1330 - 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 1331 - 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 1332 - 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 1333 - 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 1334 - EOF 1335 - git for-each-ref \ 1336 - --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ 1337 - --sort=-refname \ 1338 - --sort=taggeremail \ 1339 - --no-sort \ 1340 - --sort=taggerdate \ 1341 - "refs/tags/multi-*" >actual && 1342 - test_cmp expected actual 1343 - ' 1344 - 1345 - test_expect_success '--no-sort without subsequent --sort prints expected refs' ' 1346 - cat >expected <<-\EOF && 1347 - refs/tags/multi-ref1-100000-user1 1348 - refs/tags/multi-ref1-100000-user2 1349 - refs/tags/multi-ref1-200000-user1 1350 - refs/tags/multi-ref1-200000-user2 1351 - refs/tags/multi-ref2-100000-user1 1352 - refs/tags/multi-ref2-100000-user2 1353 - refs/tags/multi-ref2-200000-user1 1354 - refs/tags/multi-ref2-200000-user2 1355 - EOF 1356 - 1357 - # Sort the results with `sort` for a consistent comparison against 1358 - # expected 1359 - git for-each-ref \ 1360 - --format="%(refname)" \ 1361 - --no-sort \ 1362 - "refs/tags/multi-*" | sort >actual && 1363 - test_cmp expected actual 1364 - ' 1365 - 1366 - test_expect_success 'set up custom date sorting' ' 1367 - # Dates: 1368 - # - Wed Feb 07 2024 21:34:20 +0000 1369 - # - Tue Dec 14 1999 00:05:22 +0000 1370 - # - Fri Jun 04 2021 11:26:51 +0000 1371 - # - Mon Jan 22 2007 16:44:01 GMT+0000 1372 - i=1 && 1373 - for when in 1707341660 945129922 1622806011 1169484241 1374 - do 1375 - GIT_COMMITTER_DATE="@$when +0000" \ 1376 - GIT_COMMITTER_EMAIL="user@example.com" \ 1377 - git tag -m "tag $when" custom-dates-$i && 1378 - i=$(($i+1)) || return 1 1379 - done 1380 - ' 1381 - 1382 - test_expect_success 'sort by date defaults to full timestamp' ' 1383 - cat >expected <<-\EOF && 1384 - 945129922 refs/tags/custom-dates-2 1385 - 1169484241 refs/tags/custom-dates-4 1386 - 1622806011 refs/tags/custom-dates-3 1387 - 1707341660 refs/tags/custom-dates-1 1388 - EOF 1389 - 1390 - git for-each-ref \ 1391 - --format="%(creatordate:unix) %(refname)" \ 1392 - --sort=creatordate \ 1393 - "refs/tags/custom-dates-*" >actual && 1394 - test_cmp expected actual 1395 - ' 1396 - 1397 - test_expect_success 'sort by custom date format' ' 1398 - cat >expected <<-\EOF && 1399 - 00:05:22 refs/tags/custom-dates-2 1400 - 11:26:51 refs/tags/custom-dates-3 1401 - 16:44:01 refs/tags/custom-dates-4 1402 - 21:34:20 refs/tags/custom-dates-1 1403 - EOF 1404 - 1405 - git for-each-ref \ 1406 - --format="%(creatordate:format:%H:%M:%S) %(refname)" \ 1407 - --sort="creatordate:format:%H:%M:%S" \ 1408 - "refs/tags/custom-dates-*" >actual && 1409 - test_cmp expected actual 1410 - ' 1411 - 1412 - test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' 1413 - test_when_finished "git checkout main" && 1414 - git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual && 1415 - sed -e "s/^\* / /" actual >expect && 1416 - git checkout --orphan orphaned-branch && 1417 - git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual && 1418 - test_cmp expect actual 1419 - ' 1420 - 1421 - cat >trailers <<EOF 1422 - Reviewed-by: A U Thor <author@example.com> 1423 - Signed-off-by: A U Thor <author@example.com> 1424 - [ v2 updated patch description ] 1425 - Acked-by: A U Thor 1426 - <author@example.com> 1427 - EOF 1428 - 1429 - unfold () { 1430 - perl -0pe 's/\n\s+/ /g' 1431 - } 1432 - 1433 - test_expect_success 'set up trailers for next test' ' 1434 - echo "Some contents" > two && 1435 - git add two && 1436 - git commit -F - <<-EOF 1437 - trailers: this commit message has trailers 1438 - 1439 - Some message contents 1440 - 1441 - $(cat trailers) 1442 - EOF 1443 - ' 1444 - 1445 - test_trailer_option () { 1446 - if test "$#" -eq 3 1447 - then 1448 - prereq="$1" 1449 - shift 1450 - fi && 1451 - title=$1 option=$2 1452 - cat >expect 1453 - test_expect_success $prereq "$title" ' 1454 - git for-each-ref --format="%($option)" refs/heads/main >actual && 1455 - test_cmp expect actual && 1456 - git for-each-ref --format="%(contents:$option)" refs/heads/main >actual && 1457 - test_cmp expect actual 1458 - ' 1459 - } 1460 - 1461 - test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) unfolds trailers' \ 1462 - 'trailers:unfold' <<-EOF 1463 - $(unfold <trailers) 1464 - 1465 - EOF 1466 - 1467 - test_trailer_option '%(trailers:only) shows only "key: value" trailers' \ 1468 - 'trailers:only' <<-EOF 1469 - $(grep -v patch.description <trailers) 1470 - 1471 - EOF 1472 - 1473 - test_trailer_option '%(trailers:only=no,only=true) shows only "key: value" trailers' \ 1474 - 'trailers:only=no,only=true' <<-EOF 1475 - $(grep -v patch.description <trailers) 1476 - 1477 - EOF 1478 - 1479 - test_trailer_option '%(trailers:only=yes) shows only "key: value" trailers' \ 1480 - 'trailers:only=yes' <<-EOF 1481 - $(grep -v patch.description <trailers) 1482 - 1483 - EOF 1484 - 1485 - test_trailer_option '%(trailers:only=no) shows all trailers' \ 1486 - 'trailers:only=no' <<-EOF 1487 - $(cat trailers) 1488 - 1489 - EOF 1490 - 1491 - test_trailer_option PERL_TEST_HELPERS '%(trailers:only) and %(trailers:unfold) work together' \ 1492 - 'trailers:only,unfold' <<-EOF 1493 - $(grep -v patch.description <trailers | unfold) 1494 - 1495 - EOF 1496 - 1497 - test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) and %(trailers:only) work together' \ 1498 - 'trailers:unfold,only' <<-EOF 1499 - $(grep -v patch.description <trailers | unfold) 1500 - 1501 - EOF 1502 - 1503 - test_trailer_option '%(trailers:key=foo) shows that trailer' \ 1504 - 'trailers:key=Signed-off-by' <<-EOF 1505 - Signed-off-by: A U Thor <author@example.com> 1506 - 1507 - EOF 1508 - 1509 - test_trailer_option '%(trailers:key=foo) is case insensitive' \ 1510 - 'trailers:key=SiGned-oFf-bY' <<-EOF 1511 - Signed-off-by: A U Thor <author@example.com> 1512 - 1513 - EOF 1514 - 1515 - test_trailer_option '%(trailers:key=foo:) trailing colon also works' \ 1516 - 'trailers:key=Signed-off-by:' <<-EOF 1517 - Signed-off-by: A U Thor <author@example.com> 1518 - 1519 - EOF 1520 - 1521 - test_trailer_option '%(trailers:key=foo) multiple keys' \ 1522 - 'trailers:key=Reviewed-by:,key=Signed-off-by' <<-EOF 1523 - Reviewed-by: A U Thor <author@example.com> 1524 - Signed-off-by: A U Thor <author@example.com> 1525 - 1526 - EOF 1527 - 1528 - test_trailer_option '%(trailers:key=nonexistent) becomes empty' \ 1529 - 'trailers:key=Shined-off-by:' <<-EOF 1530 - 1531 - EOF 1532 - 1533 - test_trailer_option '%(trailers:key=foo) handles multiple lines even if folded' \ 1534 - 'trailers:key=Acked-by' <<-EOF 1535 - $(grep -v patch.description <trailers | grep -v Signed-off-by | grep -v Reviewed-by) 1536 - 1537 - EOF 1538 - 1539 - test_trailer_option '%(trailers:key=foo,unfold) properly unfolds' \ 1540 - 'trailers:key=Signed-Off-by,unfold' <<-EOF 1541 - $(unfold <trailers | grep Signed-off-by) 1542 - 1543 - EOF 1544 - 1545 - test_trailer_option '%(trailers:key=foo,only=no) also includes nontrailer lines' \ 1546 - 'trailers:key=Signed-off-by,only=no' <<-EOF 1547 - Signed-off-by: A U Thor <author@example.com> 1548 - $(grep patch.description <trailers) 1549 - 1550 - EOF 1551 - 1552 - test_trailer_option '%(trailers:key=foo,valueonly) shows only value' \ 1553 - 'trailers:key=Signed-off-by,valueonly' <<-EOF 1554 - A U Thor <author@example.com> 1555 - 1556 - EOF 1557 - 1558 - test_trailer_option '%(trailers:separator) changes separator' \ 1559 - 'trailers:separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF 1560 - Reviewed-by: A U Thor <author@example.com>,Signed-off-by: A U Thor <author@example.com> 1561 - EOF 1562 - 1563 - test_trailer_option '%(trailers:key_value_separator) changes key-value separator' \ 1564 - 'trailers:key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF 1565 - Reviewed-by,A U Thor <author@example.com> 1566 - Signed-off-by,A U Thor <author@example.com> 1567 - 1568 - EOF 1569 - 1570 - test_trailer_option '%(trailers:separator,key_value_separator) changes both separators' \ 1571 - 'trailers:separator=%x2C,key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF 1572 - Reviewed-by,A U Thor <author@example.com>,Signed-off-by,A U Thor <author@example.com> 1573 - EOF 1574 - 1575 - test_expect_success 'multiple %(trailers) use their own options' ' 1576 - git tag -F - tag-with-trailers <<-\EOF && 1577 - body 1578 - 1579 - one: foo 1580 - one: bar 1581 - two: baz 1582 - two: qux 1583 - EOF 1584 - t1="%(trailers:key=one,key_value_separator=W,separator=X)" && 1585 - t2="%(trailers:key=two,key_value_separator=Y,separator=Z)" && 1586 - git for-each-ref --format="$t1%0a$t2" refs/tags/tag-with-trailers >actual && 1587 - cat >expect <<-\EOF && 1588 - oneWfooXoneWbar 1589 - twoYbazZtwoYqux 1590 - EOF 1591 - test_cmp expect actual 1592 - ' 1593 - 1594 - test_failing_trailer_option () { 1595 - title=$1 option=$2 1596 - cat >expect 1597 - test_expect_success "$title" ' 1598 - # error message cannot be checked under i18n 1599 - test_must_fail git for-each-ref --format="%($option)" refs/heads/main 2>actual && 1600 - test_cmp expect actual && 1601 - test_must_fail git for-each-ref --format="%(contents:$option)" refs/heads/main 2>actual && 1602 - test_cmp expect actual 1603 - ' 1604 - } 1605 - 1606 - test_failing_trailer_option '%(trailers) rejects unknown trailers arguments' \ 1607 - 'trailers:unsupported' <<-\EOF 1608 - fatal: unknown %(trailers) argument: unsupported 1609 - EOF 1610 - 1611 - test_failing_trailer_option '%(trailers:key) without value is error' \ 1612 - 'trailers:key' <<-\EOF 1613 - fatal: expected %(trailers:key=<value>) 1614 - EOF 1615 - 1616 - test_expect_success 'if arguments, %(contents:trailers) shows error if colon is missing' ' 1617 - cat >expect <<-EOF && 1618 - fatal: unrecognized %(contents) argument: trailersonly 1619 - EOF 1620 - test_must_fail git for-each-ref --format="%(contents:trailersonly)" 2>actual && 1621 - test_cmp expect actual 1622 - ' 1623 - 1624 - test_expect_success 'basic atom: head contents:trailers' ' 1625 - git for-each-ref --format="%(contents:trailers)" refs/heads/main >actual && 1626 - sanitize_pgp <actual >actual.clean && 1627 - # git for-each-ref ends with a blank line 1628 - cat >expect <<-EOF && 1629 - $(cat trailers) 1630 - 1631 - EOF 1632 - test_cmp expect actual.clean 1633 - ' 1634 - 1635 - test_expect_success 'basic atom: rest must fail' ' 1636 - test_must_fail git for-each-ref --format="%(rest)" refs/heads/main 1637 - ' 1638 - 1639 - test_expect_success 'HEAD atom does not take arguments' ' 1640 - test_must_fail git for-each-ref --format="%(HEAD:foo)" 2>err && 1641 - echo "fatal: %(HEAD) does not take arguments" >expect && 1642 - test_cmp expect err 1643 - ' 1644 - 1645 - test_expect_success 'subject atom rejects unknown arguments' ' 1646 - test_must_fail git for-each-ref --format="%(subject:foo)" 2>err && 1647 - echo "fatal: unrecognized %(subject) argument: foo" >expect && 1648 - test_cmp expect err 1649 - ' 1650 - 1651 - test_expect_success 'refname atom rejects unknown arguments' ' 1652 - test_must_fail git for-each-ref --format="%(refname:foo)" 2>err && 1653 - echo "fatal: unrecognized %(refname) argument: foo" >expect && 1654 - test_cmp expect err 1655 - ' 1656 - 1657 - test_expect_success 'trailer parsing not fooled by --- line' ' 1658 - git commit --allow-empty -F - <<-\EOF && 1659 - this is the subject 1660 - 1661 - This is the body. The message has a "---" line which would confuse a 1662 - message+patch parser. But here we know we have only a commit message, 1663 - so we get it right. 1664 - 1665 - trailer: wrong 1666 - --- 1667 - This is more body. 1668 - 1669 - trailer: right 1670 - EOF 1671 - 1672 - { 1673 - echo "trailer: right" && 1674 - echo 1675 - } >expect && 1676 - git for-each-ref --format="%(trailers)" refs/heads/main >actual && 1677 - test_cmp expect actual 1678 - ' 1679 - 1680 - test_expect_success 'Add symbolic ref for the following tests' ' 1681 - git symbolic-ref refs/heads/sym refs/heads/main 1682 - ' 1683 - 1684 - cat >expected <<EOF 1685 - refs/heads/main 1686 - EOF 1687 - 1688 - test_expect_success 'Verify usage of %(symref) atom' ' 1689 - git for-each-ref --format="%(symref)" refs/heads/sym >actual && 1690 - test_cmp expected actual 1691 - ' 1692 - 1693 - cat >expected <<EOF 1694 - heads/main 1695 - EOF 1696 - 1697 - test_expect_success 'Verify usage of %(symref:short) atom' ' 1698 - git for-each-ref --format="%(symref:short)" refs/heads/sym >actual && 1699 - test_cmp expected actual 1700 - ' 1701 - 1702 - cat >expected <<EOF 1703 - main 1704 - heads/main 1705 - EOF 1706 - 1707 - test_expect_success 'Verify usage of %(symref:lstrip) atom' ' 1708 - git for-each-ref --format="%(symref:lstrip=2)" refs/heads/sym > actual && 1709 - git for-each-ref --format="%(symref:lstrip=-2)" refs/heads/sym >> actual && 1710 - test_cmp expected actual && 1711 - 1712 - git for-each-ref --format="%(symref:strip=2)" refs/heads/sym > actual && 1713 - git for-each-ref --format="%(symref:strip=-2)" refs/heads/sym >> actual && 1714 - test_cmp expected actual 1715 - ' 1716 - 1717 - cat >expected <<EOF 1718 - refs 1719 - refs/heads 1720 - EOF 1721 - 1722 - test_expect_success 'Verify usage of %(symref:rstrip) atom' ' 1723 - git for-each-ref --format="%(symref:rstrip=2)" refs/heads/sym > actual && 1724 - git for-each-ref --format="%(symref:rstrip=-2)" refs/heads/sym >> actual && 1725 - test_cmp expected actual 1726 - ' 1727 - 1728 - test_expect_success ':remotename and :remoteref' ' 1729 - git init remote-tests && 1730 - ( 1731 - cd remote-tests && 1732 - test_commit initial && 1733 - git branch -M main && 1734 - git remote add from fifth.coffee:blub && 1735 - git config branch.main.remote from && 1736 - git config branch.main.merge refs/heads/stable && 1737 - git remote add to southridge.audio:repo && 1738 - git config remote.to.push "refs/heads/*:refs/heads/pushed/*" && 1739 - git config branch.main.pushRemote to && 1740 - for pair in "%(upstream)=refs/remotes/from/stable" \ 1741 - "%(upstream:remotename)=from" \ 1742 - "%(upstream:remoteref)=refs/heads/stable" \ 1743 - "%(push)=refs/remotes/to/pushed/main" \ 1744 - "%(push:remotename)=to" \ 1745 - "%(push:remoteref)=refs/heads/pushed/main" 1746 - do 1747 - echo "${pair#*=}" >expect && 1748 - git for-each-ref --format="${pair%=*}" \ 1749 - refs/heads/main >actual && 1750 - test_cmp expect actual || exit 1 1751 - done && 1752 - git branch push-simple && 1753 - git config branch.push-simple.pushRemote from && 1754 - actual="$(git for-each-ref \ 1755 - --format="%(push:remotename),%(push:remoteref)" \ 1756 - refs/heads/push-simple)" && 1757 - test from, = "$actual" 1758 - ) 1759 - ' 1760 - 1761 - test_expect_success 'for-each-ref --ignore-case ignores case' ' 1762 - git for-each-ref --format="%(refname)" refs/heads/MAIN >actual && 1763 - test_must_be_empty actual && 1764 - 1765 - echo refs/heads/main >expect && 1766 - git for-each-ref --format="%(refname)" --ignore-case \ 1767 - refs/heads/MAIN >actual && 1768 - test_cmp expect actual 1769 - ' 1770 - 1771 - test_expect_success 'for-each-ref --omit-empty works' ' 1772 - git for-each-ref --format="%(refname)" >actual && 1773 - test_line_count -gt 1 actual && 1774 - git for-each-ref --format="%(if:equals=refs/heads/main)%(refname)%(then)%(refname)%(end)" --omit-empty >actual && 1775 - echo refs/heads/main >expect && 1776 - test_cmp expect actual 1777 - ' 1778 - 1779 - test_expect_success 'for-each-ref --ignore-case works on multiple sort keys' ' 1780 - # name refs numerically to avoid case-insensitive filesystem conflicts 1781 - nr=0 && 1782 - for email in a A b B 1783 - do 1784 - for subject in a A b B 1785 - do 1786 - GIT_COMMITTER_EMAIL="$email@example.com" \ 1787 - git tag -m "tag $subject" icase-$(printf %02d $nr) && 1788 - nr=$((nr+1))|| 1789 - return 1 1790 - done 1791 - done && 1792 - git for-each-ref --ignore-case \ 1793 - --format="%(taggeremail) %(subject) %(refname)" \ 1794 - --sort=refname \ 1795 - --sort=subject \ 1796 - --sort=taggeremail \ 1797 - refs/tags/icase-* >actual && 1798 - cat >expect <<-\EOF && 1799 - <a@example.com> tag a refs/tags/icase-00 1800 - <a@example.com> tag A refs/tags/icase-01 1801 - <A@example.com> tag a refs/tags/icase-04 1802 - <A@example.com> tag A refs/tags/icase-05 1803 - <a@example.com> tag b refs/tags/icase-02 1804 - <a@example.com> tag B refs/tags/icase-03 1805 - <A@example.com> tag b refs/tags/icase-06 1806 - <A@example.com> tag B refs/tags/icase-07 1807 - <b@example.com> tag a refs/tags/icase-08 1808 - <b@example.com> tag A refs/tags/icase-09 1809 - <B@example.com> tag a refs/tags/icase-12 1810 - <B@example.com> tag A refs/tags/icase-13 1811 - <b@example.com> tag b refs/tags/icase-10 1812 - <b@example.com> tag B refs/tags/icase-11 1813 - <B@example.com> tag b refs/tags/icase-14 1814 - <B@example.com> tag B refs/tags/icase-15 1815 - EOF 1816 - test_cmp expect actual 1817 - ' 1818 - 1819 - test_expect_success 'for-each-ref reports broken tags' ' 1820 - git tag -m "good tag" broken-tag-good HEAD && 1821 - git cat-file tag broken-tag-good >good && 1822 - sed s/commit/blob/ <good >bad && 1823 - bad=$(git hash-object -w -t tag bad) && 1824 - git update-ref refs/tags/broken-tag-bad $bad && 1825 - test_must_fail git for-each-ref --format="%(*objectname)" \ 1826 - refs/tags/broken-tag-* 1827 - ' 1828 - 1829 - test_expect_success 'set up tag with signature and no blank lines' ' 1830 - git tag -F - fake-sig-no-blanks <<-\EOF 1831 - this is the subject 1832 - -----BEGIN PGP SIGNATURE----- 1833 - not a real signature, but we just care about the 1834 - subject/body parsing. It is important here that 1835 - there are no blank lines in the signature. 1836 - -----END PGP SIGNATURE----- 1837 - EOF 1838 - ' 1839 - 1840 - test_atom refs/tags/fake-sig-no-blanks contents:subject 'this is the subject' 1841 - test_atom refs/tags/fake-sig-no-blanks contents:body '' 1842 - test_atom refs/tags/fake-sig-no-blanks contents:signature "$sig" 1843 - 1844 - test_expect_success 'set up tag with CRLF signature' ' 1845 - append_cr <<-\EOF | 1846 - this is the subject 1847 - -----BEGIN PGP SIGNATURE----- 1848 - 1849 - not a real signature, but we just care about 1850 - the subject/body parsing. It is important here 1851 - that there is a blank line separating this 1852 - from the signature header. 1853 - -----END PGP SIGNATURE----- 1854 - EOF 1855 - git tag -F - --cleanup=verbatim fake-sig-crlf 1856 - ' 1857 - 1858 - test_atom refs/tags/fake-sig-crlf contents:subject 'this is the subject' 1859 - test_atom refs/tags/fake-sig-crlf contents:body '' 1860 - 1861 - # CRLF is retained in the signature, so we have to pass our expected value 1862 - # through append_cr. But test_atom requires a shell string, which means command 1863 - # substitution, and the shell will strip trailing newlines from the output of 1864 - # the substitution. Hack around it by adding and then removing a dummy line. 1865 - sig_crlf="$(printf "%s" "$sig" | append_cr; echo dummy)" 1866 - sig_crlf=${sig_crlf%dummy} 1867 - test_atom refs/tags/fake-sig-crlf contents:signature "$sig_crlf" 1868 - 1869 - test_expect_success 'set up tag with signature and trailers' ' 1870 - git tag -F - fake-sig-trailer <<-\EOF 1871 - this is the subject 1872 - 1873 - this is the body 1874 - 1875 - My-Trailer: foo 1876 - -----BEGIN PGP SIGNATURE----- 1877 - 1878 - not a real signature, but we just care about the 1879 - subject/body/trailer parsing. 1880 - -----END PGP SIGNATURE----- 1881 - EOF 1882 - ' 1883 - 1884 - # use "separator=" here to suppress the terminating newline 1885 - test_atom refs/tags/fake-sig-trailer trailers:separator= 'My-Trailer: foo' 1886 - 1887 - test_expect_success 'git for-each-ref --stdin: empty' ' 1888 - >in && 1889 - git for-each-ref --format="%(refname)" --stdin <in >actual && 1890 - git for-each-ref --format="%(refname)" >expect && 1891 - test_cmp expect actual 1892 - ' 1893 - 1894 - test_expect_success 'git for-each-ref --stdin: fails if extra args' ' 1895 - >in && 1896 - test_must_fail git for-each-ref --format="%(refname)" \ 1897 - --stdin refs/heads/extra <in 2>err && 1898 - grep "unknown arguments supplied with --stdin" err 1899 - ' 1900 - 1901 - test_expect_success 'git for-each-ref --stdin: matches' ' 1902 - cat >in <<-EOF && 1903 - refs/tags/multi* 1904 - refs/heads/amb* 1905 - EOF 1906 - 1907 - cat >expect <<-EOF && 1908 - refs/heads/ambiguous 1909 - refs/tags/multi-ref1-100000-user1 1910 - refs/tags/multi-ref1-100000-user2 1911 - refs/tags/multi-ref1-200000-user1 1912 - refs/tags/multi-ref1-200000-user2 1913 - refs/tags/multi-ref2-100000-user1 1914 - refs/tags/multi-ref2-100000-user2 1915 - refs/tags/multi-ref2-200000-user1 1916 - refs/tags/multi-ref2-200000-user2 1917 - refs/tags/multiline 1918 - EOF 1919 - 1920 - git for-each-ref --format="%(refname)" --stdin <in >actual && 1921 - test_cmp expect actual 1922 - ' 1923 - 1924 - test_expect_success 'git for-each-ref with non-existing refs' ' 1925 - cat >in <<-EOF && 1926 - refs/heads/this-ref-does-not-exist 1927 - refs/tags/bogus 1928 - EOF 1929 - 1930 - git for-each-ref --format="%(refname)" --stdin <in >actual && 1931 - test_must_be_empty actual && 1932 - 1933 - xargs git for-each-ref --format="%(refname)" <in >actual && 1934 - test_must_be_empty actual 1935 - ' 1936 - 1937 - test_expect_success 'git for-each-ref with nested tags' ' 1938 - git tag -am "Normal tag" nested/base HEAD && 1939 - git tag -am "Nested tag" nested/nest1 refs/tags/nested/base && 1940 - git tag -am "Double nested tag" nested/nest2 refs/tags/nested/nest1 && 1941 - 1942 - head_oid="$(git rev-parse HEAD)" && 1943 - base_tag_oid="$(git rev-parse refs/tags/nested/base)" && 1944 - nest1_tag_oid="$(git rev-parse refs/tags/nested/nest1)" && 1945 - nest2_tag_oid="$(git rev-parse refs/tags/nested/nest2)" && 1946 - 1947 - cat >expect <<-EOF && 1948 - refs/tags/nested/base $base_tag_oid tag $head_oid commit 1949 - refs/tags/nested/nest1 $nest1_tag_oid tag $head_oid commit 1950 - refs/tags/nested/nest2 $nest2_tag_oid tag $head_oid commit 1951 - EOF 1952 - 1953 - git for-each-ref \ 1954 - --format="%(refname) %(objectname) %(objecttype) %(*objectname) %(*objecttype)" \ 1955 - refs/tags/nested/ >actual && 1956 - test_cmp expect actual 1957 - ' 1958 - 1959 - test_expect_success 'is-base atom with non-commits' ' 1960 - git for-each-ref --format="%(is-base:HEAD) %(refname)" >out 2>err && 1961 - grep "(HEAD) refs/heads/main" out && 1962 - 1963 - test_line_count = 2 err && 1964 - grep "error: object .* is a commit, not a blob" err && 1965 - grep "error: bad tag pointer to" err 1966 - ' 1967 - 1968 - GRADE_FORMAT="%(signature:grade)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" 1969 - TRUSTLEVEL_FORMAT="%(signature:trustlevel)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" 1970 - 1971 - test_expect_success GPG 'setup for signature atom using gpg' ' 1972 - git checkout -b signed && 1973 - 1974 - test_when_finished "test_unconfig commit.gpgSign" && 1975 - 1976 - echo "1" >file && 1977 - git add file && 1978 - test_tick && 1979 - git commit -S -m "file: 1" && 1980 - git tag first-signed && 1981 - 1982 - echo "2" >file && 1983 - test_tick && 1984 - git commit -a -m "file: 2" && 1985 - git tag second-unsigned && 1986 - 1987 - git config commit.gpgSign 1 && 1988 - echo "3" >file && 1989 - test_tick && 1990 - git commit -a --no-gpg-sign -m "file: 3" && 1991 - git tag third-unsigned && 1992 - 1993 - test_tick && 1994 - git rebase -f HEAD^^ && git tag second-signed HEAD^ && 1995 - git tag third-signed && 1996 - 1997 - echo "4" >file && 1998 - test_tick && 1999 - git commit -a -SB7227189 -m "file: 4" && 2000 - git tag fourth-signed && 2001 - 2002 - echo "5" >file && 2003 - test_tick && 2004 - git commit -a --no-gpg-sign -m "file: 5" && 2005 - git tag fifth-unsigned && 2006 - 2007 - echo "6" >file && 2008 - test_tick && 2009 - git commit -a --no-gpg-sign -m "file: 6" && 2010 - 2011 - test_tick && 2012 - git rebase -f HEAD^^ && 2013 - git tag fifth-signed HEAD^ && 2014 - git tag sixth-signed && 2015 - 2016 - echo "7" >file && 2017 - test_tick && 2018 - git commit -a --no-gpg-sign -m "file: 7" && 2019 - git tag seventh-unsigned 2020 - ' 2021 - 2022 - test_expect_success GPGSSH 'setup for signature atom using ssh' ' 2023 - test_when_finished "test_unconfig gpg.format user.signingkey" && 2024 - 2025 - test_config gpg.format ssh && 2026 - test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && 2027 - echo "8" >file && 2028 - test_tick && 2029 - git add file && 2030 - git commit -S -m "file: 8" && 2031 - git tag eighth-signed-ssh 2032 - ' 2033 - 2034 - test_expect_success GPG2 'bare signature atom' ' 2035 - git verify-commit first-signed 2>expect && 2036 - echo >>expect && 2037 - git for-each-ref refs/tags/first-signed \ 2038 - --format="%(signature)" >actual && 2039 - test_cmp expect actual 2040 - ' 2041 - 2042 - test_expect_success GPG 'show good signature with custom format' ' 2043 - git verify-commit first-signed && 2044 - cat >expect <<-\EOF && 2045 - G 2046 - 13B6F51ECDDE430D 2047 - C O Mitter <committer@example.com> 2048 - 73D758744BE721698EC54E8713B6F51ECDDE430D 2049 - 73D758744BE721698EC54E8713B6F51ECDDE430D 2050 - EOF 2051 - git for-each-ref refs/tags/first-signed \ 2052 - --format="$GRADE_FORMAT" >actual && 2053 - test_cmp expect actual 2054 - ' 2055 - test_expect_success GPGSSH 'show good signature with custom format with ssh' ' 2056 - test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && 2057 - FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && 2058 - cat >expect.tmpl <<-\EOF && 2059 - G 2060 - FINGERPRINT 2061 - principal with number 1 2062 - FINGERPRINT 2063 - 2064 - EOF 2065 - sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && 2066 - git for-each-ref refs/tags/eighth-signed-ssh \ 2067 - --format="$GRADE_FORMAT" >actual && 2068 - test_cmp expect actual 2069 - ' 2070 - 2071 - test_expect_success GPG 'signature atom with grade option and bad signature' ' 2072 - git cat-file commit third-signed >raw && 2073 - sed -e "s/^file: 3/file: 3 forged/" raw >forged1 && 2074 - FORGED1=$(git hash-object -w -t commit forged1) && 2075 - git update-ref refs/tags/third-signed "$FORGED1" && 2076 - test_must_fail git verify-commit "$FORGED1" && 2077 - 2078 - cat >expect <<-\EOF && 2079 - B 2080 - 13B6F51ECDDE430D 2081 - C O Mitter <committer@example.com> 2082 - 2083 - 2084 - EOF 2085 - git for-each-ref refs/tags/third-signed \ 2086 - --format="$GRADE_FORMAT" >actual && 2087 - test_cmp expect actual 2088 - ' 2089 - 2090 - test_expect_success GPG 'show untrusted signature with custom format' ' 2091 - cat >expect <<-\EOF && 2092 - U 2093 - 65A0EEA02E30CAD7 2094 - Eris Discordia <discord@example.net> 2095 - F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 2096 - D4BE22311AD3131E5EDA29A461092E85B7227189 2097 - EOF 2098 - git for-each-ref refs/tags/fourth-signed \ 2099 - --format="$GRADE_FORMAT" >actual && 2100 - test_cmp expect actual 2101 - ' 2102 - 2103 - test_expect_success GPG 'show untrusted signature with undefined trust level' ' 2104 - cat >expect <<-\EOF && 2105 - undefined 2106 - 65A0EEA02E30CAD7 2107 - Eris Discordia <discord@example.net> 2108 - F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 2109 - D4BE22311AD3131E5EDA29A461092E85B7227189 2110 - EOF 2111 - git for-each-ref refs/tags/fourth-signed \ 2112 - --format="$TRUSTLEVEL_FORMAT" >actual && 2113 - test_cmp expect actual 2114 - ' 2115 - 2116 - test_expect_success GPG 'show untrusted signature with ultimate trust level' ' 2117 - cat >expect <<-\EOF && 2118 - ultimate 2119 - 13B6F51ECDDE430D 2120 - C O Mitter <committer@example.com> 2121 - 73D758744BE721698EC54E8713B6F51ECDDE430D 2122 - 73D758744BE721698EC54E8713B6F51ECDDE430D 2123 - EOF 2124 - git for-each-ref refs/tags/sixth-signed \ 2125 - --format="$TRUSTLEVEL_FORMAT" >actual && 2126 - test_cmp expect actual 2127 - ' 2128 - 2129 - test_expect_success GPG 'show unknown signature with custom format' ' 2130 - cat >expect <<-\EOF && 2131 - E 2132 - 13B6F51ECDDE430D 2133 - 2134 - 2135 - 2136 - EOF 2137 - GNUPGHOME="$GNUPGHOME_NOT_USED" git for-each-ref \ 2138 - refs/tags/sixth-signed --format="$GRADE_FORMAT" >actual && 2139 - test_cmp expect actual 2140 - ' 2141 - 2142 - test_expect_success GPG 'show lack of signature with custom format' ' 2143 - cat >expect <<-\EOF && 2144 - N 2145 - 2146 - 2147 - 2148 - 2149 - EOF 2150 - git for-each-ref refs/tags/seventh-unsigned \ 2151 - --format="$GRADE_FORMAT" >actual && 2152 - test_cmp expect actual 2153 - ' 17 + . "$TEST_DIRECTORY"/for-each-ref-tests.sh 2154 18 2155 19 test_done