{"thread":{"id":"66070","subject":"[PATCH 0/2] t: add and use a commit_body test helper","startedAt":"2026-07-26T22:48:17Z","lastAt":"2026-07-30T19:38:35Z","messageCount":11,"participants":["Shlok Kulshreshtha","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"549048","messageId":"20260726224803.45131-1-diy2903@gmail.com","threadId":"66070","inReplyTo":null,"subject":"[PATCH 0/2] t: add and use a commit_body test helper","fromName":"Shlok Kulshreshtha","fromEmail":"diy2903@gmail.com","sentAt":"2026-07-26T22:48:01Z","receivedAt":"2026-07-26T22:48:17Z","isPatch":true,"body":"While reviewing \"t7614: avoid hiding git's exit code in a pipe\"\n(now in master as b6b276974e), Junio pointed out that the pattern\nfixed there by hand -- \"cat-file the commit object, and strip away\nthe object header with sed\" -- recurs throughout the test suite, and\nsuggested factoring it into a helper (cf. <xmqq1pd4m4ea.fsf@gitster.g>):\n\n    commit_body () {\n        git cat-file commit \"$1\" >.commit &&\n        sed -e \"1,/^$/d\" .commit &&\n        rm -f .commit\n    }\n\nI said I would take this up as a follow-up once t7614 landed. It has,\nso here it is.\n\nScope:\n\n  1/2 adds the helper to t/test-lib-functions.sh, following Junio's\n      sketch, with a t/README entry.\n\n  2/2 converts the existing call sites: 60 sites across 11 files.\n      The idiom appears in four equivalent spellings (piped or\n      written to a file first, \"sed -e\" or plain \"sed\", \"\\$\" or \"$\"\n      in the address) that all produce byte-identical output and\n      collapse to the same commit_body call. Two sites needed more\n      than a mechanical substitution and are explained individually\n      in that commit's message; a few more are left alone because\n      they are not extracting a commit's message body at all (email\n      headers, a hand-built object for fsck, a .patch file).\n\nConverting the piped sites also closes the same exit-code hole t7614\nfixed: the exit status of a pipeline is that of its last command, so\na crashing \"git cat-file\" was previously masked by \"sed\" succeeding\non empty input.\n\nVerification: all 11 touched test scripts pass in full (build clean,\nno new failures), and a deliberately failing \"git cat-file\" now fails\na converted test that previously passed, confirming the exit-code fix\nis real.\n\nShlok Kulshreshtha (2):\n  test-lib-functions: add commit_body helper\n  t: use commit_body to extract commit message bodies\n\n t/README                                  | 11 ++++\n t/t3405-rebase-malformed.sh               |  8 +--\n t/t3408-rebase-multi-line.sh              |  4 +-\n t/t3434-rebase-i18n.sh                    |  3 +-\n t/t3900-i18n-commit.sh                    |  4 +-\n t/t4150-am.sh                             |  8 +--\n t/t7500-commit-template-squash-signoff.sh |  4 +-\n t/t7501-commit-basic-functionality.sh     | 21 +++----\n t/t7502-commit-porcelain.sh               | 77 ++++++++---------------\n t/t7600-merge.sh                          | 14 ++---\n t/t7604-merge-custom-message.sh           | 18 ++----\n t/t7614-merge-signoff.sh                  |  9 +--\n t/test-lib-functions.sh                   |  8 +++\n 13 files changed, 81 insertions(+), 108 deletions(-)\n\n-- \n2.52.0\n\n"},{"id":"549049","messageId":"20260726224803.45131-2-diy2903@gmail.com","threadId":"66070","inReplyTo":"20260726224803.45131-1-diy2903@gmail.com","subject":"[PATCH 1/2] test-lib-functions: add commit_body helper","fromName":"Shlok Kulshreshtha","fromEmail":"diy2903@gmail.com","sentAt":"2026-07-26T22:48:02Z","receivedAt":"2026-07-26T22:48:22Z","isPatch":true,"body":"Extracting the message body of a commit -- running \"git cat-file commit\"\nand stripping everything up to and including the first blank line with\n\"sed\" -- is spelled out in about 60 places across the test suite.\n\nAdd a helper for it, so that the operation is written once instead of\nbeing copied around.\n\nThe commit object goes to a temporary file rather than into a pipe,\nbecause a pipeline reports only its last command's exit status, so a\nfailure of \"git cat-file\" would go unnoticed.\n\nSigned-off-by: Shlok Kulshreshtha <diy2903@gmail.com>\n---\n t/README                | 11 +++++++++++\n t/test-lib-functions.sh |  8 ++++++++\n 2 files changed, 19 insertions(+)\n\ndiff --git a/t/README b/t/README\nindex 4252774f86..9a9daaf2af 100644\n--- a/t/README\n+++ b/t/README\n@@ -945,6 +945,17 @@ see test-lib-functions.sh for the full list and their options.\n    Merges the given rev using the given message.  Like test_commit,\n    creates a tag and calls test_tick before committing.\n \n+ - commit_body <rev>\n+\n+   Print the message body of <rev>, i.e. the contents of its commit\n+   object with the header removed.  Use this instead of piping\n+   \"git cat-file commit\" into \"sed\", which would hide a failure of\n+   the git command.\n+\n+   Example:\n+\n+\tcommit_body HEAD >actual\n+\n  - test_set_prereq <prereq>\n \n    Set a test prerequisite to be used later with test_have_prereq. The\ndiff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh\nindex 809c662124..03bf31d8ef 100644\n--- a/t/test-lib-functions.sh\n+++ b/t/test-lib-functions.sh\n@@ -1433,6 +1433,14 @@ test_commit_message () {\n \ttest_cmp \"$msg_file\" actual.msg\n }\n \n+# Print the message body of a commit\n+# Usage: commit_body <rev>\n+commit_body () {\n+\tgit cat-file commit \"$1\" >.commit &&\n+\tsed -e \"1,/^$/d\" .commit &&\n+\trm -f .commit\n+}\n+\n # Compare paths respecting core.ignoreCase\n test_cmp_fspath () {\n \tif test \"x$1\" = \"x$2\"\n-- \n2.52.0\n\n"},{"id":"549050","messageId":"20260726224803.45131-3-diy2903@gmail.com","threadId":"66070","inReplyTo":"20260726224803.45131-1-diy2903@gmail.com","subject":"[PATCH 2/2] t: use commit_body to extract commit message bodies","fromName":"Shlok Kulshreshtha","fromEmail":"diy2903@gmail.com","sentAt":"2026-07-26T22:48:03Z","receivedAt":"2026-07-26T22:48:27Z","isPatch":true,"body":"Replace the \"git cat-file commit | sed\" idiom with commit_body across the\ntest suite: 60 sites in 11 files. The idiom appears in four equivalent\nspellings -- piped or written to a file first, \"sed -e\" or plain \"sed\",\n\"\\$\" or \"$\" in the address -- all producing byte-identical output; they\nall collapse to the same commit_body call.\n\nTwo sites needed more than a mechanical substitution:\n\n* t7600.sh (\"merge --no-ff --edit\") greps the raw commit object for a\n  phrase before stripping its header for the final comparison. The\n  phrase is part of the commit body, not the header, so the grep can\n  run against the already-stripped body instead, letting both steps\n  share one commit_body call.\n\n* t3900-i18n-commit.sh pipes the stripped body into \"iconv\" to test\n  re-encoding. Piping commit_body's output into \"iconv\" would reintroduce\n  an exit-code hole one line after removing it elsewhere, so this site\n  writes the body to a file first and reads that, keeping the &&-chain\n  intact.\n\nSome greps for sed -e \"1,/^\\*$/d\" left unconverted, as they are not extracting a commit's message body:\n\n* t9001-send-email.sh strips mail headers from a message file, not a\n  commit object.\n* t1450-fsck.sh strips the header off a hand-built commit object while\n  constructing a malformed one for fsck to reject.\n* t4014-format-patch.sh runs the same sed address on a \".patch\" file,\n  with an additional expression.\n\nAll converted files pass in full, and a deliberately failing\n\"git cat-file\" now fails a converted test that previously passed.\n\nSigned-off-by: Shlok Kulshreshtha <diy2903@gmail.com>\n---\n t/t3405-rebase-malformed.sh               |  8 +--\n t/t3408-rebase-multi-line.sh              |  4 +-\n t/t3434-rebase-i18n.sh                    |  3 +-\n t/t3900-i18n-commit.sh                    |  4 +-\n t/t4150-am.sh                             |  8 +--\n t/t7500-commit-template-squash-signoff.sh |  4 +-\n t/t7501-commit-basic-functionality.sh     | 21 +++----\n t/t7502-commit-porcelain.sh               | 77 ++++++++---------------\n t/t7600-merge.sh                          | 14 ++---\n t/t7604-merge-custom-message.sh           | 18 ++----\n t/t7614-merge-signoff.sh                  |  9 +--\n 11 files changed, 62 insertions(+), 108 deletions(-)\n\ndiff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh\nindex 2524331861..271195fc11 100755\n--- a/t/t3405-rebase-malformed.sh\n+++ b/t/t3405-rebase-malformed.sh\n@@ -37,7 +37,7 @@ test_expect_success setup '\n \ttest_tick &&\n \tgit commit -F F &&\n \n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >F0 &&\n+\tcommit_body HEAD >F0 &&\n \n \tgit checkout diff-in-message &&\n \techo \"commit log message containing a diff\" >G &&\n@@ -48,7 +48,7 @@ test_expect_success setup '\n \ttest_tick &&\n \tgit commit -F G &&\n \n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >G0 &&\n+\tcommit_body HEAD >G0 &&\n \n \tgit checkout empty-message-merge &&\n \techo file3 >file3 &&\n@@ -66,7 +66,7 @@ test_expect_success setup '\n test_expect_success 'rebase commit with multi-line subject' '\n \n \tgit rebase main multi-line-subject &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >F1 &&\n+\tcommit_body HEAD >F1 &&\n \n \ttest_cmp F0 F1 &&\n \ttest_cmp F F0\n@@ -74,7 +74,7 @@ test_expect_success 'rebase commit with multi-line subject' '\n \n test_expect_success 'rebase commit with diff in message' '\n \tgit rebase main diff-in-message &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >G1 &&\n+\tcommit_body HEAD >G1 &&\n \ttest_cmp G0 G1 &&\n \ttest_cmp G G0\n '\ndiff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh\nindex cde3562e3a..2ab89e1a7d 100755\n--- a/t/t3408-rebase-multi-line.sh\n+++ b/t/t3408-rebase-multi-line.sh\n@@ -50,8 +50,8 @@ test_expect_success rebase '\n \n \tgit checkout side &&\n \tgit rebase main &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >actual &&\n-\tgit cat-file commit side@{1} | sed -e \"1,/^\\$/d\" >expect &&\n+\tcommit_body HEAD >actual &&\n+\tcommit_body side@{1} >expect &&\n \ttest_cmp expect actual\n \n '\ndiff --git a/t/t3434-rebase-i18n.sh b/t/t3434-rebase-i18n.sh\nindex 8c94fdffc4..0f93a239f8 100755\n--- a/t/t3434-rebase-i18n.sh\n+++ b/t/t3434-rebase-i18n.sh\n@@ -27,8 +27,7 @@ fi\n \n compare_msg () {\n \ticonv -f \"$2\" -t \"$3\" \"$TEST_DIRECTORY/t3434/$1\" >expect &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n }\n \ndiff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh\nindex 3c930ec202..b3f03bcbd0 100755\n--- a/t/t3900-i18n-commit.sh\n+++ b/t/t3900-i18n-commit.sh\n@@ -232,8 +232,8 @@ test_commit_autosquash_multi_encoding () {\n \t\tgit rev-list HEAD >actual &&\n \t\ttest_line_count = 3 actual &&\n \t\ticonv -f $old -t UTF-8 \"$TEST_DIRECTORY\"/t3900/$msg >expect &&\n-\t\tgit cat-file commit HEAD^ >raw &&\n-\t\t(sed \"1,/^$/d\" raw | iconv -f $new -t utf-8) >actual &&\n+\t\tcommit_body HEAD^ >raw &&\n+\t\ticonv -f $new -t utf-8 <raw >actual &&\n \t\ttest_cmp expect actual\n \t'\n }\ndiff --git a/t/t4150-am.sh b/t/t4150-am.sh\nindex 61c3ce9018..ee96223668 100755\n--- a/t/t4150-am.sh\n+++ b/t/t4150-am.sh\n@@ -1018,7 +1018,7 @@ test_expect_success 'am -s unexpected trailer block' '\n \tSigned-off-by: J C H <j@c.h>\n \tEOF\n \tgit commit -F msg &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >original &&\n+\tcommit_body HEAD >original &&\n \tgit format-patch --stdout -1 >patch &&\n \n \tgit reset --hard HEAD^ &&\n@@ -1027,7 +1027,7 @@ test_expect_success 'am -s unexpected trailer block' '\n \t\tcat original &&\n \t\techo \"Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\"\n \t) >expect &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual &&\n \n \tcat >msg <<-\\EOF &&\n@@ -1038,7 +1038,7 @@ test_expect_success 'am -s unexpected trailer block' '\n \tEOF\n \tgit reset HEAD^ &&\n \tgit commit -F msg file &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >original &&\n+\tcommit_body HEAD >original &&\n \tgit format-patch --stdout -1 >patch &&\n \n \tgit reset --hard HEAD^ &&\n@@ -1049,7 +1049,7 @@ test_expect_success 'am -s unexpected trailer block' '\n \t\techo &&\n \t\techo \"Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\"\n \t) >expect &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \ndiff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh\nindex 66aff8e097..5e782ad8d7 100755\n--- a/t/t7500-commit-template-squash-signoff.sh\n+++ b/t/t7500-commit-template-squash-signoff.sh\n@@ -59,7 +59,7 @@ test_expect_success 'nonexistent template file in config should return error' '\n test_expect_success 'nonexistent optional template file in config' '\n \ttest_config commit.template \":(optional)$(pwd)\"/notexist &&\n \tGIT_EDITOR=\"echo hello >\" git commit --allow-empty &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >actual &&\n+\tcommit_body HEAD >actual &&\n \techo hello >expect &&\n \ttest_cmp expect actual\n '\n@@ -204,7 +204,7 @@ EOF\n test_expect_success '--signoff' '\n \techo \"yet another content *narf*\" >> foo &&\n \techo \"zort\" | git commit -s -F - foo &&\n-\tgit cat-file commit HEAD | sed \"1,/^\\$/d\" > output &&\n+\tcommit_body HEAD >output &&\n \ttest_cmp expect output\n '\n \ndiff --git a/t/t7501-commit-basic-functionality.sh b/t/t7501-commit-basic-functionality.sh\nindex 7794babe46..d0af38df20 100755\n--- a/t/t7501-commit-basic-functionality.sh\n+++ b/t/t7501-commit-basic-functionality.sh\n@@ -491,8 +491,7 @@ test_expect_success 'sign off (1)' '\n \techo 1 >positive &&\n \tgit add positive &&\n \tgit commit -s -m \"thank you\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo thank you &&\n \t\techo &&\n@@ -511,8 +510,7 @@ test_expect_success 'sign off (2)' '\n \tgit commit -s -m \"thank you\n \n $existing\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo thank you &&\n \t\techo &&\n@@ -532,8 +530,7 @@ test_expect_success 'signoff gap' '\n \tgit commit -s -m \"welcome\n \n $alt\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo welcome &&\n \t\techo &&\n@@ -553,8 +550,7 @@ test_expect_success 'signoff gap 2' '\n \n We have now\n $alt\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo welcome &&\n \t\techo &&\n@@ -575,8 +571,7 @@ test_expect_success 'signoff respects trailer config' '\n \n non-trailer line\n Myfooter: x\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo subject &&\n \t\techo &&\n@@ -593,8 +588,7 @@ Myfooter: x\" &&\n \n non-trailer line\n Myfooter: x\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo subject &&\n \t\techo &&\n@@ -626,8 +620,7 @@ test_expect_success 'multiple -m' '\n \t>negative &&\n \tgit add negative &&\n \tgit commit -m \"one\" -m \"two\" -m \"three\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo one &&\n \t\techo &&\ndiff --git a/t/t7502-commit-porcelain.sh b/t/t7502-commit-porcelain.sh\nindex 62e3970e3f..2adfe70b3d 100755\n--- a/t/t7502-commit-porcelain.sh\n+++ b/t/t7502-commit-porcelain.sh\n@@ -175,8 +175,7 @@ test_expect_success 'commit --trailer with \"=\"' '\n \tReported-by: C3 E3\n \tMentored-by: C4 E4\n \tEOF\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -195,8 +194,7 @@ test_expect_success 'commit --trailer with -c and \"replace\" as ifexists' '\n \t\tcommit --trailer \"Mentored-by: C4 E4\" \\\n \t\t --trailer \"Helped-by: C3 E3\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -217,8 +215,7 @@ test_expect_success 'commit --trailer with -c and \"add\" as ifexists' '\n \t\tcommit --trailer \"Reported-by: C3 E3\" \\\n \t\t--trailer \"Mentored-by: C4 E4\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -238,8 +235,7 @@ test_expect_success 'commit --trailer with -c and \"donothing\" as ifexists' '\n \t\tcommit --trailer \"Mentored-by: C5 E5\" \\\n \t\t--trailer \"Reviewed-by: C6 E6\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -259,8 +255,7 @@ test_expect_success 'commit --trailer with -c and \"addIfDifferent\" as ifexists'\n \t\tcommit --trailer \"Reported-by: C3 E3\" \\\n \t\t--trailer \"Mentored-by: C5 E5\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -280,8 +275,7 @@ test_expect_success 'commit --trailer with -c and \"addIfDifferentNeighbor\" as if\n \t\tcommit --trailer \"Mentored-by: C4 E4\" \\\n \t\t--trailer \"Reported-by: C3 E3\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -302,8 +296,7 @@ test_expect_success 'commit --trailer with -c and \"end\" as where' '\n \t\tcommit --trailer \"Reported-by: C3 E3\" \\\n \t\t--trailer \"Mentored-by: C4 E4\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -323,8 +316,7 @@ test_expect_success 'commit --trailer with -c and \"start\" as where' '\n \t\tcommit --trailer \"Signed-off-by: C O Mitter <committer@example.com>\" \\\n \t\t--trailer \"Signed-off-by: C1 E1\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -344,8 +336,7 @@ test_expect_success 'commit --trailer with -c and \"after\" as where' '\n \t\tcommit --trailer \"Mentored-by: C4 E4\" \\\n \t\t--trailer \"Mentored-by: C5 E5\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -366,8 +357,7 @@ test_expect_success 'commit --trailer with -c and \"before\" as where' '\n \t\tcommit --trailer \"Mentored-by: C3 E3\" \\\n \t\t--trailer \"Mentored-by: C2 E2\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -387,8 +377,7 @@ test_expect_success 'commit --trailer with -c and \"donothing\" as ifmissing' '\n \t\tcommit --trailer \"Helped-by: C5 E5\" \\\n \t\t--trailer \"Based-by: C6 E6\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -409,8 +398,7 @@ test_expect_success 'commit --trailer with -c and \"add\" as ifmissing' '\n \t\tcommit --trailer \"Helped-by: C5 E5\" \\\n \t\t--trailer \"Based-by: C6 E6\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -424,8 +412,7 @@ test_expect_success 'commit --trailer with -c ack.key ' '\n \tEOF\n \tgit -c trailer.ack.key=\"Acked-by\" \\\n \t\tcommit --trailer \"ack = Peff\" -m \"hello\" &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -440,8 +427,7 @@ test_expect_success 'commit --trailer with -c and \":=#\" as separators' '\n \tgit -c trailer.separators=\":=#\" \\\n \t\t-c trailer.bug.key=\"Bug #\" \\\n \t\tcommit --trailer \"bug = 42\" -m \"I hate bug\" &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -461,8 +447,7 @@ test_expect_success 'commit --trailer with -c and command' '\n \t\t-c trailer.report.command=\"NAME=\\\"\\$ARG\\\"; test -n \\\"\\$NAME\\\" && \\\n \t\tgit log --author=\\\"\\$NAME\\\" -1 --format=\\\"format:%aN <%aE>\\\" || true\" \\\n \t\tcommit --trailer \"report = author\" --amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -480,8 +465,7 @@ test_expect_success 'commit --trailer not confused by --- separator' '\n \t\techo &&\n \t\techo \"my-trailer: value\"\n \t} >expected &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -498,8 +482,7 @@ test_expect_success 'commit --trailer with --verbose' '\n \t\techo &&\n \t\techo \"my-trailer: value\"\n \t} >expected &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -508,7 +491,7 @@ test_expect_success 'multiple -m' '\n \t>negative &&\n \tgit add negative &&\n \tgit commit -m \"one\" -m \"two\" -m \"three\" &&\n-\tactual=$(git cat-file commit HEAD >tmp && sed -e \"1,/^\\$/d\" tmp && rm tmp) &&\n+\tactual=$(commit_body HEAD) &&\n \texpected=$(test_write_lines \"one\" \"\" \"two\" \"\" \"three\") &&\n \ttest \"z$actual\" = \"z$expected\"\n \n@@ -545,8 +528,7 @@ test_expect_success 'cleanup commit messages (verbatim option,-t)' '\n \n \techo >>negative &&\n \tgit commit --cleanup=verbatim --no-status -t expect -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -555,8 +537,7 @@ test_expect_success 'cleanup commit messages (verbatim option,-F)' '\n \n \techo >>negative &&\n \tgit commit --cleanup=verbatim -F expect -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -565,8 +546,7 @@ test_expect_success 'cleanup commit messages (verbatim option,-m)' '\n \n \techo >>negative &&\n \tgit commit --cleanup=verbatim -m \"$mesg_with_comment_and_newlines\" -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -577,8 +557,7 @@ test_expect_success 'cleanup commit messages (whitespace option,-F)' '\n \ttest_write_lines \"\" \"# text\" \"\" >text &&\n \techo \"# text\" >expect &&\n \tgit commit --cleanup=whitespace -F text -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -605,8 +584,7 @@ test_expect_success 'cleanup commit messages (scissors option,-F,-e)' '\n \t# to be kept, too\n \tEOF\n \tgit commit --cleanup=scissors -e -F text -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -618,8 +596,7 @@ test_expect_success 'cleanup commit messages (scissors option,-F,-e, scissors on\n \tto be removed\n \tEOF\n \tgit commit --cleanup=scissors -e -F text -a --allow-empty-message &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_must_be_empty actual\n '\n \n@@ -629,8 +606,7 @@ test_expect_success 'cleanup commit messages (strip option,-F)' '\n \ttest_write_lines \"\" \"# text\" \"sample\" \"\" >text &&\n \techo sample >expect &&\n \tgit commit --cleanup=strip -F text -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -849,8 +825,7 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo\n \n \tgit reset --hard &&\n \tgit commit -s -m \"hello: kitty\" --allow-empty &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_line_count = 3 actual\n \n '\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex 7f2a1db16d..64cb83284c 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -332,8 +332,7 @@ test_expect_success 'merge --squash c3 with c7' '\n \t# Conflicts:\n \t#\tfile\n \tEOF\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -363,8 +362,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '\n \t# Conflicts:\n \t#\tfile\n \tEOF\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -387,8 +385,7 @@ test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' '\n \t# Conflicts:\n \t#\tfile\n \tEOF\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -989,9 +986,8 @@ test_expect_success 'merge --no-ff --edit' '\n \tgit reset --hard c0 &&\n \tEDITOR=./editor git merge --no-ff --edit c1 &&\n \tverify_parents $c0 $c1 &&\n-\tgit cat-file commit HEAD >raw &&\n-\ttest_grep \"work done on the side branch\" raw &&\n-\tsed \"1,/^$/d\" >actual raw &&\n+\tcommit_body HEAD >actual &&\n+\ttest_grep \"work done on the side branch\" actual &&\n \ttest_cmp expected actual\n '\n \ndiff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh\nindex cd4f9607dc..3a7d1ae858 100755\n--- a/t/t7604-merge-custom-message.sh\n+++ b/t/t7604-merge-custom-message.sh\n@@ -36,16 +36,14 @@ test_expect_success 'setup' '\n test_expect_success 'merge c2 with a custom message' '\n \tgit reset --hard c1 &&\n \tgit merge -m \"$(cat exp.subject)\" c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp exp.subject actual\n '\n \n test_expect_success 'merge --log appends to custom message' '\n \tgit reset --hard c1 &&\n \tgit merge --log -m \"$(cat exp.subject)\" c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp exp.log actual\n '\n \n@@ -61,8 +59,7 @@ test_expect_success 'prepare file with comment line and trailing newlines'  '\n test_expect_success 'cleanup commit messages (verbatim option)' '\n \tgit reset --hard c1 &&\n \tgit merge --cleanup=verbatim -F expect c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -71,8 +68,7 @@ test_expect_success 'cleanup commit messages (whitespace option)' '\n \ttest_write_lines \"\" \"# text\" \"\" >text &&\n \techo \"# text\" >expect &&\n \tgit merge --cleanup=whitespace -F text c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -97,8 +93,7 @@ test_expect_success 'cleanup merge messages (scissors option)' '\n \t# to be kept, too\n \tEOF\n \tgit merge --cleanup=scissors -e -F text c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -107,8 +102,7 @@ test_expect_success 'cleanup commit messages (strip option)' '\n \ttest_write_lines \"\" \"# text\" \"sample\" \"\" >text &&\n \techo sample >expect &&\n \tgit merge --cleanup=strip -F text c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \ndiff --git a/t/t7614-merge-signoff.sh b/t/t7614-merge-signoff.sh\nindex e58bf07b7a..b078eaf8a3 100755\n--- a/t/t7614-merge-signoff.sh\n+++ b/t/t7614-merge-signoff.sh\n@@ -45,8 +45,7 @@ test_expect_success 'git merge --signoff adds a sign-off line' '\n \ttest_commit main-branch-2 file2 2 &&\n \tgit checkout other-branch &&\n \tgit merge main --signoff --no-edit &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected-signed actual\n '\n \n@@ -56,8 +55,7 @@ test_expect_success 'git merge does not add a sign-off line' '\n \ttest_commit main-branch-3 file3 3 &&\n \tgit checkout other-branch &&\n \tgit merge main --no-edit &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected-unsigned actual\n '\n \n@@ -67,8 +65,7 @@ test_expect_success 'git merge --no-signoff flag cancels --signoff flag' '\n \ttest_commit main-branch-4 file4 4 &&\n \tgit checkout other-branch &&\n \tgit merge main --no-edit --signoff --no-signoff &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected-unsigned actual\n '\n \n-- \n2.52.0\n\n"},{"id":"549072","messageId":"xmqqldawq24y.fsf@gitster.g","threadId":"66070","inReplyTo":"20260726224803.45131-1-diy2903@gmail.com","subject":"Re: [PATCH 0/2] t: add and use a commit_body test helper","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-07-27T08:15:41Z","receivedAt":"2026-07-27T08:15:44Z","isPatch":true,"body":"Shlok Kulshreshtha <diy2903@gmail.com> writes:\n\n>  t/README                                  | 11 ++++\n>  t/t3405-rebase-malformed.sh               |  8 +--\n>  t/t3408-rebase-multi-line.sh              |  4 +-\n>  t/t3434-rebase-i18n.sh                    |  3 +-\n>  t/t3900-i18n-commit.sh                    |  4 +-\n>  t/t4150-am.sh                             |  8 +--\n>  t/t7500-commit-template-squash-signoff.sh |  4 +-\n>  t/t7501-commit-basic-functionality.sh     | 21 +++----\n>  t/t7502-commit-porcelain.sh               | 77 ++++++++---------------\n>  t/t7600-merge.sh                          | 14 ++---\n>  t/t7604-merge-custom-message.sh           | 18 ++----\n>  t/t7614-merge-signoff.sh                  |  9 +--\n>  t/test-lib-functions.sh                   |  8 +++\n>  13 files changed, 81 insertions(+), 108 deletions(-)\n\nDoesn't 'message_body' t7509 has follow the same pattern to hide\nexit code from 'git cat-file commit'?\n\nThanks.\n\n\n"},{"id":"549075","messageId":"20260727092810.71405-1-diy2903@gmail.com","threadId":"66070","inReplyTo":"xmqqldawq24y.fsf@gitster.g","subject":"Re: [PATCH 0/2] t: add and use a commit_body test helper","fromName":"Shlok Kulshreshtha","fromEmail":"diy2903@gmail.com","sentAt":"2026-07-27T09:28:10Z","receivedAt":"2026-07-27T09:28:17Z","isPatch":true,"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Doesn't 'message_body' t7509 has follow the same pattern to hide\n> exit code from 'git cat-file commit'?\n\nYes, you are right, I had missed that one. t7509 defines its own\nlocal message_body() helper:\n\n    message_body () {\n\tgit cat-file commit \"$1\" |\n\tsed -e '1,/^$/d'\n    }\n\nwhich pipes \"git cat-file commit\" into \"sed\", the same\nexit-code-hiding idiom commit_body was introduced to replace.\nWhile rechecking, I found one more site with the same problem in\nt3404-rebase-interactive.sh, a spacing variant of the idiom\n(\"sed -e 1,/^\\$/d\" without quotes around the address) that didn't\nmatch the four spellings I had searched for in the original patch.\n\nI've replaced both -- the message_body helper (and its call sites)\nin t7509, and the inline pipe in t3404 -- with commit_body. Will send\na v2 with these folded in.\n\nThanks.\n"},{"id":"549078","messageId":"20260727095656.75496-1-diy2903@gmail.com","threadId":"66070","inReplyTo":"xmqqldawq24y.fsf@gitster.g","subject":"[PATCH v2 0/2] t: add and use a commit_body test helper","fromName":"Shlok Kulshreshtha","fromEmail":"diy2903@gmail.com","sentAt":"2026-07-27T09:56:54Z","receivedAt":"2026-07-27T09:57:02Z","isPatch":true,"body":"Junio pointed out that t7509-commit-authorship.sh defines its own local\nmessage_body() helper that wraps the same \"git cat-file commit | sed\"\nidiom commit_body was introduced to replace, which the first version of\nthis series missed. Rechecking the whole idiom by its sed\naddress, rather than by grepping for \"cat-file\", turned up one more\ninline occurrence with a spacing/escaping variant in\nt3404-rebase-interactive.sh that also didn't match the four spellings\nenumerated in v1.\n\nChanges since v1:\n\n  2/2: fold in t7509's message_body helper (drop it, convert its six\n       call sites to commit_body) and the missed inline site in t3404.\n       Site count is now 61 in 12 files, plus the removed helper.\n\nShlok Kulshreshtha (2):\n  test-lib-functions: add commit_body helper\n  t: use commit_body to extract commit message bodies\n\n t/README                                  | 11 ++++\n t/t3404-rebase-interactive.sh             |  2 +-\n t/t3405-rebase-malformed.sh               |  8 +--\n t/t3408-rebase-multi-line.sh              |  4 +-\n t/t3434-rebase-i18n.sh                    |  3 +-\n t/t3900-i18n-commit.sh                    |  4 +-\n t/t4150-am.sh                             |  8 +--\n t/t7500-commit-template-squash-signoff.sh |  4 +-\n t/t7501-commit-basic-functionality.sh     | 21 +++----\n t/t7502-commit-porcelain.sh               | 77 ++++++++---------------\n t/t7509-commit-authorship.sh              | 23 +++----\n t/t7600-merge.sh                          | 14 ++---\n t/t7604-merge-custom-message.sh           | 18 ++----\n t/t7614-merge-signoff.sh                  |  9 +--\n t/test-lib-functions.sh                   |  8 +++\n 15 files changed, 91 insertions(+), 123 deletions(-)\n\n-- \n2.52.0\n\n"},{"id":"549079","messageId":"20260727095656.75496-2-diy2903@gmail.com","threadId":"66070","inReplyTo":"20260727095656.75496-1-diy2903@gmail.com","subject":"[PATCH v2 1/2] test-lib-functions: add commit_body helper","fromName":"Shlok Kulshreshtha","fromEmail":"diy2903@gmail.com","sentAt":"2026-07-27T09:56:55Z","receivedAt":"2026-07-27T09:57:05Z","isPatch":true,"body":"Extracting the message body of a commit -- running \"git cat-file commit\"\nand stripping everything up to and including the first blank line with\n\"sed\" -- is spelled out in about 60 places across the test suite.\n\nAdd a helper for it, so that the operation is written once instead of\nbeing copied around.\n\nThe commit object goes to a temporary file rather than into a pipe,\nbecause a pipeline reports only its last command's exit status, so a\nfailure of \"git cat-file\" would go unnoticed.\n\nSigned-off-by: Shlok Kulshreshtha <diy2903@gmail.com>\n---\n t/README                | 11 +++++++++++\n t/test-lib-functions.sh |  8 ++++++++\n 2 files changed, 19 insertions(+)\n\ndiff --git a/t/README b/t/README\nindex 4252774f86..9a9daaf2af 100644\n--- a/t/README\n+++ b/t/README\n@@ -945,6 +945,17 @@ see test-lib-functions.sh for the full list and their options.\n    Merges the given rev using the given message.  Like test_commit,\n    creates a tag and calls test_tick before committing.\n \n+ - commit_body <rev>\n+\n+   Print the message body of <rev>, i.e. the contents of its commit\n+   object with the header removed.  Use this instead of piping\n+   \"git cat-file commit\" into \"sed\", which would hide a failure of\n+   the git command.\n+\n+   Example:\n+\n+\tcommit_body HEAD >actual\n+\n  - test_set_prereq <prereq>\n \n    Set a test prerequisite to be used later with test_have_prereq. The\ndiff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh\nindex 809c662124..03bf31d8ef 100644\n--- a/t/test-lib-functions.sh\n+++ b/t/test-lib-functions.sh\n@@ -1433,6 +1433,14 @@ test_commit_message () {\n \ttest_cmp \"$msg_file\" actual.msg\n }\n \n+# Print the message body of a commit\n+# Usage: commit_body <rev>\n+commit_body () {\n+\tgit cat-file commit \"$1\" >.commit &&\n+\tsed -e \"1,/^$/d\" .commit &&\n+\trm -f .commit\n+}\n+\n # Compare paths respecting core.ignoreCase\n test_cmp_fspath () {\n \tif test \"x$1\" = \"x$2\"\n-- \n2.52.0\n\n"},{"id":"549080","messageId":"20260727095656.75496-3-diy2903@gmail.com","threadId":"66070","inReplyTo":"20260727095656.75496-1-diy2903@gmail.com","subject":"[PATCH v2 2/2] t: use commit_body to extract commit message bodies","fromName":"Shlok Kulshreshtha","fromEmail":"diy2903@gmail.com","sentAt":"2026-07-27T09:56:56Z","receivedAt":"2026-07-27T09:57:12Z","isPatch":true,"body":"Replace the \"git cat-file commit | sed\" idiom with commit_body across the\ntest suite: 61 sites in 12 files, plus one local helper that wrapped the\nsame idiom. The idiom appears in four equivalent spellings -- piped or\nwritten to a file first, \"sed -e\" or plain \"sed\", \"\\$\" or \"$\" in the\naddress -- all producing byte-identical output; they all collapse to the\nsame commit_body call.\n\nt7509-commit-authorship.sh defined its own local message_body() helper\naround the idiom instead of spelling it out at each call site; remove the\nhelper and convert its six call sites to commit_body directly.\n\nTwo sites needed more than a mechanical substitution:\n\n* t7600.sh (\"merge --no-ff --edit\") greps the raw commit object for a\n  phrase before stripping its header for the final comparison. The\n  phrase is part of the commit body, not the header, so the grep can\n  run against the already-stripped body instead, letting both steps\n  share one commit_body call.\n\n* t3900-i18n-commit.sh pipes the stripped body into \"iconv\" to test\n  re-encoding. Piping commit_body's output into \"iconv\" would reintroduce\n  an exit-code hole one line after removing it elsewhere, so this site\n  writes the body to a file first and reads that, keeping the &&-chain\n  intact.\n\nSome greps for sed -e \"1,/^\\*$/d\" left unconverted, as they are not extracting a commit's message body:\n\n* t9001-send-email.sh strips mail headers from a message file, not a\n  commit object.\n* t1450-fsck.sh strips the header off a hand-built commit object while\n  constructing a malformed one for fsck to reject.\n* t4014-format-patch.sh runs the same sed address on a \".patch\" file,\n  with an additional expression.\n\nAll converted files pass in full, and a deliberately failing\n\"git cat-file\" now fails a converted test that previously passed.\n\nSigned-off-by: Shlok Kulshreshtha <diy2903@gmail.com>\n---\n t/t3404-rebase-interactive.sh             |  2 +-\n t/t3405-rebase-malformed.sh               |  8 +--\n t/t3408-rebase-multi-line.sh              |  4 +-\n t/t3434-rebase-i18n.sh                    |  3 +-\n t/t3900-i18n-commit.sh                    |  4 +-\n t/t4150-am.sh                             |  8 +--\n t/t7500-commit-template-squash-signoff.sh |  4 +-\n t/t7501-commit-basic-functionality.sh     | 21 +++----\n t/t7502-commit-porcelain.sh               | 77 ++++++++---------------\n t/t7509-commit-authorship.sh              | 23 +++----\n t/t7600-merge.sh                          | 14 ++---\n t/t7604-merge-custom-message.sh           | 18 ++----\n t/t7614-merge-signoff.sh                  |  9 +--\n 13 files changed, 72 insertions(+), 123 deletions(-)\n\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex e64816770a..a952e2b49d 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -484,7 +484,7 @@ test_expect_success 'squash and fixup generate correct log messages' '\n \t\t\tEXPECT_HEADER_COUNT=4 \\\n \t\t\tgit rebase -i $base\n \t) &&\n-\tgit cat-file commit HEAD | sed -e 1,/^\\$/d > actual-squash-fixup &&\n+\tcommit_body HEAD >actual-squash-fixup &&\n \ttest_cmp expect-squash-fixup actual-squash-fixup &&\n \tgit cat-file commit HEAD@{2} >actual &&\n \ttest_grep \"^# This is a combination of 3 commits\\.\" actual &&\ndiff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh\nindex 2524331861..271195fc11 100755\n--- a/t/t3405-rebase-malformed.sh\n+++ b/t/t3405-rebase-malformed.sh\n@@ -37,7 +37,7 @@ test_expect_success setup '\n \ttest_tick &&\n \tgit commit -F F &&\n \n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >F0 &&\n+\tcommit_body HEAD >F0 &&\n \n \tgit checkout diff-in-message &&\n \techo \"commit log message containing a diff\" >G &&\n@@ -48,7 +48,7 @@ test_expect_success setup '\n \ttest_tick &&\n \tgit commit -F G &&\n \n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >G0 &&\n+\tcommit_body HEAD >G0 &&\n \n \tgit checkout empty-message-merge &&\n \techo file3 >file3 &&\n@@ -66,7 +66,7 @@ test_expect_success setup '\n test_expect_success 'rebase commit with multi-line subject' '\n \n \tgit rebase main multi-line-subject &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >F1 &&\n+\tcommit_body HEAD >F1 &&\n \n \ttest_cmp F0 F1 &&\n \ttest_cmp F F0\n@@ -74,7 +74,7 @@ test_expect_success 'rebase commit with multi-line subject' '\n \n test_expect_success 'rebase commit with diff in message' '\n \tgit rebase main diff-in-message &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >G1 &&\n+\tcommit_body HEAD >G1 &&\n \ttest_cmp G0 G1 &&\n \ttest_cmp G G0\n '\ndiff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh\nindex cde3562e3a..2ab89e1a7d 100755\n--- a/t/t3408-rebase-multi-line.sh\n+++ b/t/t3408-rebase-multi-line.sh\n@@ -50,8 +50,8 @@ test_expect_success rebase '\n \n \tgit checkout side &&\n \tgit rebase main &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^\\$/d\" >actual &&\n-\tgit cat-file commit side@{1} | sed -e \"1,/^\\$/d\" >expect &&\n+\tcommit_body HEAD >actual &&\n+\tcommit_body side@{1} >expect &&\n \ttest_cmp expect actual\n \n '\ndiff --git a/t/t3434-rebase-i18n.sh b/t/t3434-rebase-i18n.sh\nindex 8c94fdffc4..0f93a239f8 100755\n--- a/t/t3434-rebase-i18n.sh\n+++ b/t/t3434-rebase-i18n.sh\n@@ -27,8 +27,7 @@ fi\n \n compare_msg () {\n \ticonv -f \"$2\" -t \"$3\" \"$TEST_DIRECTORY/t3434/$1\" >expect &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n }\n \ndiff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh\nindex 3c930ec202..b3f03bcbd0 100755\n--- a/t/t3900-i18n-commit.sh\n+++ b/t/t3900-i18n-commit.sh\n@@ -232,8 +232,8 @@ test_commit_autosquash_multi_encoding () {\n \t\tgit rev-list HEAD >actual &&\n \t\ttest_line_count = 3 actual &&\n \t\ticonv -f $old -t UTF-8 \"$TEST_DIRECTORY\"/t3900/$msg >expect &&\n-\t\tgit cat-file commit HEAD^ >raw &&\n-\t\t(sed \"1,/^$/d\" raw | iconv -f $new -t utf-8) >actual &&\n+\t\tcommit_body HEAD^ >raw &&\n+\t\ticonv -f $new -t utf-8 <raw >actual &&\n \t\ttest_cmp expect actual\n \t'\n }\ndiff --git a/t/t4150-am.sh b/t/t4150-am.sh\nindex 61c3ce9018..ee96223668 100755\n--- a/t/t4150-am.sh\n+++ b/t/t4150-am.sh\n@@ -1018,7 +1018,7 @@ test_expect_success 'am -s unexpected trailer block' '\n \tSigned-off-by: J C H <j@c.h>\n \tEOF\n \tgit commit -F msg &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >original &&\n+\tcommit_body HEAD >original &&\n \tgit format-patch --stdout -1 >patch &&\n \n \tgit reset --hard HEAD^ &&\n@@ -1027,7 +1027,7 @@ test_expect_success 'am -s unexpected trailer block' '\n \t\tcat original &&\n \t\techo \"Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\"\n \t) >expect &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual &&\n \n \tcat >msg <<-\\EOF &&\n@@ -1038,7 +1038,7 @@ test_expect_success 'am -s unexpected trailer block' '\n \tEOF\n \tgit reset HEAD^ &&\n \tgit commit -F msg file &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >original &&\n+\tcommit_body HEAD >original &&\n \tgit format-patch --stdout -1 >patch &&\n \n \tgit reset --hard HEAD^ &&\n@@ -1049,7 +1049,7 @@ test_expect_success 'am -s unexpected trailer block' '\n \t\techo &&\n \t\techo \"Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\"\n \t) >expect &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \ndiff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh\nindex 66aff8e097..5e782ad8d7 100755\n--- a/t/t7500-commit-template-squash-signoff.sh\n+++ b/t/t7500-commit-template-squash-signoff.sh\n@@ -59,7 +59,7 @@ test_expect_success 'nonexistent template file in config should return error' '\n test_expect_success 'nonexistent optional template file in config' '\n \ttest_config commit.template \":(optional)$(pwd)\"/notexist &&\n \tGIT_EDITOR=\"echo hello >\" git commit --allow-empty &&\n-\tgit cat-file commit HEAD | sed -e \"1,/^$/d\" >actual &&\n+\tcommit_body HEAD >actual &&\n \techo hello >expect &&\n \ttest_cmp expect actual\n '\n@@ -204,7 +204,7 @@ EOF\n test_expect_success '--signoff' '\n \techo \"yet another content *narf*\" >> foo &&\n \techo \"zort\" | git commit -s -F - foo &&\n-\tgit cat-file commit HEAD | sed \"1,/^\\$/d\" > output &&\n+\tcommit_body HEAD >output &&\n \ttest_cmp expect output\n '\n \ndiff --git a/t/t7501-commit-basic-functionality.sh b/t/t7501-commit-basic-functionality.sh\nindex 7794babe46..d0af38df20 100755\n--- a/t/t7501-commit-basic-functionality.sh\n+++ b/t/t7501-commit-basic-functionality.sh\n@@ -491,8 +491,7 @@ test_expect_success 'sign off (1)' '\n \techo 1 >positive &&\n \tgit add positive &&\n \tgit commit -s -m \"thank you\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo thank you &&\n \t\techo &&\n@@ -511,8 +510,7 @@ test_expect_success 'sign off (2)' '\n \tgit commit -s -m \"thank you\n \n $existing\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo thank you &&\n \t\techo &&\n@@ -532,8 +530,7 @@ test_expect_success 'signoff gap' '\n \tgit commit -s -m \"welcome\n \n $alt\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo welcome &&\n \t\techo &&\n@@ -553,8 +550,7 @@ test_expect_success 'signoff gap 2' '\n \n We have now\n $alt\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo welcome &&\n \t\techo &&\n@@ -575,8 +571,7 @@ test_expect_success 'signoff respects trailer config' '\n \n non-trailer line\n Myfooter: x\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo subject &&\n \t\techo &&\n@@ -593,8 +588,7 @@ Myfooter: x\" &&\n \n non-trailer line\n Myfooter: x\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo subject &&\n \t\techo &&\n@@ -626,8 +620,7 @@ test_expect_success 'multiple -m' '\n \t>negative &&\n \tgit add negative &&\n \tgit commit -m \"one\" -m \"two\" -m \"three\" &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \t(\n \t\techo one &&\n \t\techo &&\ndiff --git a/t/t7502-commit-porcelain.sh b/t/t7502-commit-porcelain.sh\nindex 62e3970e3f..2adfe70b3d 100755\n--- a/t/t7502-commit-porcelain.sh\n+++ b/t/t7502-commit-porcelain.sh\n@@ -175,8 +175,7 @@ test_expect_success 'commit --trailer with \"=\"' '\n \tReported-by: C3 E3\n \tMentored-by: C4 E4\n \tEOF\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -195,8 +194,7 @@ test_expect_success 'commit --trailer with -c and \"replace\" as ifexists' '\n \t\tcommit --trailer \"Mentored-by: C4 E4\" \\\n \t\t --trailer \"Helped-by: C3 E3\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -217,8 +215,7 @@ test_expect_success 'commit --trailer with -c and \"add\" as ifexists' '\n \t\tcommit --trailer \"Reported-by: C3 E3\" \\\n \t\t--trailer \"Mentored-by: C4 E4\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -238,8 +235,7 @@ test_expect_success 'commit --trailer with -c and \"donothing\" as ifexists' '\n \t\tcommit --trailer \"Mentored-by: C5 E5\" \\\n \t\t--trailer \"Reviewed-by: C6 E6\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -259,8 +255,7 @@ test_expect_success 'commit --trailer with -c and \"addIfDifferent\" as ifexists'\n \t\tcommit --trailer \"Reported-by: C3 E3\" \\\n \t\t--trailer \"Mentored-by: C5 E5\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -280,8 +275,7 @@ test_expect_success 'commit --trailer with -c and \"addIfDifferentNeighbor\" as if\n \t\tcommit --trailer \"Mentored-by: C4 E4\" \\\n \t\t--trailer \"Reported-by: C3 E3\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\"  commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -302,8 +296,7 @@ test_expect_success 'commit --trailer with -c and \"end\" as where' '\n \t\tcommit --trailer \"Reported-by: C3 E3\" \\\n \t\t--trailer \"Mentored-by: C4 E4\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -323,8 +316,7 @@ test_expect_success 'commit --trailer with -c and \"start\" as where' '\n \t\tcommit --trailer \"Signed-off-by: C O Mitter <committer@example.com>\" \\\n \t\t--trailer \"Signed-off-by: C1 E1\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -344,8 +336,7 @@ test_expect_success 'commit --trailer with -c and \"after\" as where' '\n \t\tcommit --trailer \"Mentored-by: C4 E4\" \\\n \t\t--trailer \"Mentored-by: C5 E5\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -366,8 +357,7 @@ test_expect_success 'commit --trailer with -c and \"before\" as where' '\n \t\tcommit --trailer \"Mentored-by: C3 E3\" \\\n \t\t--trailer \"Mentored-by: C2 E2\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -387,8 +377,7 @@ test_expect_success 'commit --trailer with -c and \"donothing\" as ifmissing' '\n \t\tcommit --trailer \"Helped-by: C5 E5\" \\\n \t\t--trailer \"Based-by: C6 E6\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -409,8 +398,7 @@ test_expect_success 'commit --trailer with -c and \"add\" as ifmissing' '\n \t\tcommit --trailer \"Helped-by: C5 E5\" \\\n \t\t--trailer \"Based-by: C6 E6\" \\\n \t\t--amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -424,8 +412,7 @@ test_expect_success 'commit --trailer with -c ack.key ' '\n \tEOF\n \tgit -c trailer.ack.key=\"Acked-by\" \\\n \t\tcommit --trailer \"ack = Peff\" -m \"hello\" &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -440,8 +427,7 @@ test_expect_success 'commit --trailer with -c and \":=#\" as separators' '\n \tgit -c trailer.separators=\":=#\" \\\n \t\t-c trailer.bug.key=\"Bug #\" \\\n \t\tcommit --trailer \"bug = 42\" -m \"I hate bug\" &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -461,8 +447,7 @@ test_expect_success 'commit --trailer with -c and command' '\n \t\t-c trailer.report.command=\"NAME=\\\"\\$ARG\\\"; test -n \\\"\\$NAME\\\" && \\\n \t\tgit log --author=\\\"\\$NAME\\\" -1 --format=\\\"format:%aN <%aE>\\\" || true\" \\\n \t\tcommit --trailer \"report = author\" --amend &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -480,8 +465,7 @@ test_expect_success 'commit --trailer not confused by --- separator' '\n \t\techo &&\n \t\techo \"my-trailer: value\"\n \t} >expected &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -498,8 +482,7 @@ test_expect_success 'commit --trailer with --verbose' '\n \t\techo &&\n \t\techo \"my-trailer: value\"\n \t} >expected &&\n-\tgit cat-file commit HEAD >commit.msg &&\n-\tsed -e \"1,/^\\$/d\" commit.msg >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n@@ -508,7 +491,7 @@ test_expect_success 'multiple -m' '\n \t>negative &&\n \tgit add negative &&\n \tgit commit -m \"one\" -m \"two\" -m \"three\" &&\n-\tactual=$(git cat-file commit HEAD >tmp && sed -e \"1,/^\\$/d\" tmp && rm tmp) &&\n+\tactual=$(commit_body HEAD) &&\n \texpected=$(test_write_lines \"one\" \"\" \"two\" \"\" \"three\") &&\n \ttest \"z$actual\" = \"z$expected\"\n \n@@ -545,8 +528,7 @@ test_expect_success 'cleanup commit messages (verbatim option,-t)' '\n \n \techo >>negative &&\n \tgit commit --cleanup=verbatim --no-status -t expect -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -555,8 +537,7 @@ test_expect_success 'cleanup commit messages (verbatim option,-F)' '\n \n \techo >>negative &&\n \tgit commit --cleanup=verbatim -F expect -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -565,8 +546,7 @@ test_expect_success 'cleanup commit messages (verbatim option,-m)' '\n \n \techo >>negative &&\n \tgit commit --cleanup=verbatim -m \"$mesg_with_comment_and_newlines\" -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -577,8 +557,7 @@ test_expect_success 'cleanup commit messages (whitespace option,-F)' '\n \ttest_write_lines \"\" \"# text\" \"\" >text &&\n \techo \"# text\" >expect &&\n \tgit commit --cleanup=whitespace -F text -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -605,8 +584,7 @@ test_expect_success 'cleanup commit messages (scissors option,-F,-e)' '\n \t# to be kept, too\n \tEOF\n \tgit commit --cleanup=scissors -e -F text -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -618,8 +596,7 @@ test_expect_success 'cleanup commit messages (scissors option,-F,-e, scissors on\n \tto be removed\n \tEOF\n \tgit commit --cleanup=scissors -e -F text -a --allow-empty-message &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_must_be_empty actual\n '\n \n@@ -629,8 +606,7 @@ test_expect_success 'cleanup commit messages (strip option,-F)' '\n \ttest_write_lines \"\" \"# text\" \"sample\" \"\" >text &&\n \techo sample >expect &&\n \tgit commit --cleanup=strip -F text -a &&\n-\tgit cat-file -p HEAD >raw &&\n-\tsed -e \"1,/^\\$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n \n '\n@@ -849,8 +825,7 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo\n \n \tgit reset --hard &&\n \tgit commit -s -m \"hello: kitty\" --allow-empty &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_line_count = 3 actual\n \n '\ndiff --git a/t/t7509-commit-authorship.sh b/t/t7509-commit-authorship.sh\nindex 8e373b566b..561c19a219 100755\n--- a/t/t7509-commit-authorship.sh\n+++ b/t/t7509-commit-authorship.sh\n@@ -12,11 +12,6 @@ author_header () {\n \tsed -n -e '/^$/q' -e '/^author /p'\n }\n \n-message_body () {\n-\tgit cat-file commit \"$1\" |\n-\tsed -e '1,/^$/d'\n-}\n-\n test_expect_success '-C option copies authorship and message' '\n \ttest_commit --author Frigate\\ \\<flying@over.world\\> \\\n \t\t\"Initial Commit\" foo Initial Initial &&\n@@ -27,8 +22,8 @@ test_expect_success '-C option copies authorship and message' '\n \tauthor_header HEAD >actual &&\n \ttest_cmp expect actual &&\n \n-\tmessage_body Initial >expect &&\n-\tmessage_body HEAD >actual &&\n+\tcommit_body Initial >expect &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -40,8 +35,8 @@ test_expect_success '-C option copies only the message with --reset-author' '\n \tauthor_header HEAD >actual &&\n \ttest_cmp expect actual &&\n \n-\tmessage_body Initial >expect &&\n-\tmessage_body HEAD >actual &&\n+\tcommit_body Initial >expect &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -62,8 +57,8 @@ test_expect_success '-c option copies only the message with --reset-author' '\n \tauthor_header HEAD >actual &&\n \ttest_cmp expect actual &&\n \n-\tmessage_body Initial >expect &&\n-\tmessage_body HEAD >actual &&\n+\tcommit_body Initial >expect &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -77,7 +72,7 @@ test_expect_success '--amend option copies authorship' '\n \ttest_cmp expect actual &&\n \n \techo \"amend test\" >expect &&\n-\tmessage_body HEAD >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -124,7 +119,7 @@ test_expect_success '--reset-author makes the commit ours even with --amend opti\n \ttest_cmp expect actual &&\n \n \techo \"Changed again\" >expect &&\n-\tmessage_body HEAD >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -157,7 +152,7 @@ test_expect_success 'commit respects CHERRY_PICK_HEAD and MERGE_MSG' '\n \ttest_cmp expect actual &&\n \n \techo \"This is a MERGE_MSG\" >expect &&\n-\tmessage_body HEAD >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex 7f2a1db16d..64cb83284c 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -332,8 +332,7 @@ test_expect_success 'merge --squash c3 with c7' '\n \t# Conflicts:\n \t#\tfile\n \tEOF\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -363,8 +362,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '\n \t# Conflicts:\n \t#\tfile\n \tEOF\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -387,8 +385,7 @@ test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' '\n \t# Conflicts:\n \t#\tfile\n \tEOF\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -989,9 +986,8 @@ test_expect_success 'merge --no-ff --edit' '\n \tgit reset --hard c0 &&\n \tEDITOR=./editor git merge --no-ff --edit c1 &&\n \tverify_parents $c0 $c1 &&\n-\tgit cat-file commit HEAD >raw &&\n-\ttest_grep \"work done on the side branch\" raw &&\n-\tsed \"1,/^$/d\" >actual raw &&\n+\tcommit_body HEAD >actual &&\n+\ttest_grep \"work done on the side branch\" actual &&\n \ttest_cmp expected actual\n '\n \ndiff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh\nindex cd4f9607dc..3a7d1ae858 100755\n--- a/t/t7604-merge-custom-message.sh\n+++ b/t/t7604-merge-custom-message.sh\n@@ -36,16 +36,14 @@ test_expect_success 'setup' '\n test_expect_success 'merge c2 with a custom message' '\n \tgit reset --hard c1 &&\n \tgit merge -m \"$(cat exp.subject)\" c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp exp.subject actual\n '\n \n test_expect_success 'merge --log appends to custom message' '\n \tgit reset --hard c1 &&\n \tgit merge --log -m \"$(cat exp.subject)\" c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp exp.log actual\n '\n \n@@ -61,8 +59,7 @@ test_expect_success 'prepare file with comment line and trailing newlines'  '\n test_expect_success 'cleanup commit messages (verbatim option)' '\n \tgit reset --hard c1 &&\n \tgit merge --cleanup=verbatim -F expect c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -71,8 +68,7 @@ test_expect_success 'cleanup commit messages (whitespace option)' '\n \ttest_write_lines \"\" \"# text\" \"\" >text &&\n \techo \"# text\" >expect &&\n \tgit merge --cleanup=whitespace -F text c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -97,8 +93,7 @@ test_expect_success 'cleanup merge messages (scissors option)' '\n \t# to be kept, too\n \tEOF\n \tgit merge --cleanup=scissors -e -F text c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \n@@ -107,8 +102,7 @@ test_expect_success 'cleanup commit messages (strip option)' '\n \ttest_write_lines \"\" \"# text\" \"sample\" \"\" >text &&\n \techo sample >expect &&\n \tgit merge --cleanup=strip -F text c2 &&\n-\tgit cat-file commit HEAD >raw &&\n-\tsed -e \"1,/^$/d\" raw >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expect actual\n '\n \ndiff --git a/t/t7614-merge-signoff.sh b/t/t7614-merge-signoff.sh\nindex e58bf07b7a..b078eaf8a3 100755\n--- a/t/t7614-merge-signoff.sh\n+++ b/t/t7614-merge-signoff.sh\n@@ -45,8 +45,7 @@ test_expect_success 'git merge --signoff adds a sign-off line' '\n \ttest_commit main-branch-2 file2 2 &&\n \tgit checkout other-branch &&\n \tgit merge main --signoff --no-edit &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected-signed actual\n '\n \n@@ -56,8 +55,7 @@ test_expect_success 'git merge does not add a sign-off line' '\n \ttest_commit main-branch-3 file3 3 &&\n \tgit checkout other-branch &&\n \tgit merge main --no-edit &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected-unsigned actual\n '\n \n@@ -67,8 +65,7 @@ test_expect_success 'git merge --no-signoff flag cancels --signoff flag' '\n \ttest_commit main-branch-4 file4 4 &&\n \tgit checkout other-branch &&\n \tgit merge main --no-edit --signoff --no-signoff &&\n-\tgit cat-file commit HEAD >commit &&\n-\tsed -e \"1,/^\\$/d\" commit >actual &&\n+\tcommit_body HEAD >actual &&\n \ttest_cmp expected-unsigned actual\n '\n \n-- \n2.52.0\n\n"},{"id":"549232","messageId":"xmqqpl05o5n7.fsf@gitster.g","threadId":"66070","inReplyTo":"20260727095656.75496-3-diy2903@gmail.com","subject":"Re: [PATCH v2 2/2] t: use commit_body to extract commit message bodies","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-07-29T21:19:40Z","receivedAt":"2026-07-29T21:19:42Z","isPatch":true,"body":"Shlok Kulshreshtha <diy2903@gmail.com> writes:\n\n>  t/t3404-rebase-interactive.sh             |  2 +-\n>  t/t3405-rebase-malformed.sh               |  8 +--\n>  t/t3408-rebase-multi-line.sh              |  4 +-\n>  t/t3434-rebase-i18n.sh                    |  3 +-\n>  t/t3900-i18n-commit.sh                    |  4 +-\n>  t/t4150-am.sh                             |  8 +--\n>  t/t7500-commit-template-squash-signoff.sh |  4 +-\n>  t/t7501-commit-basic-functionality.sh     | 21 +++----\n>  t/t7502-commit-porcelain.sh               | 77 ++++++++---------------\n>  t/t7509-commit-authorship.sh              | 23 +++----\n>  t/t7600-merge.sh                          | 14 ++---\n>  t/t7604-merge-custom-message.sh           | 18 ++----\n>  t/t7614-merge-signoff.sh                  |  9 +--\n>  13 files changed, 72 insertions(+), 123 deletions(-)\n\nI would not claim to have checked all of these changes, but I did\nspot check a handful and they all looked reasonable.\n\nShall we mark the topic for 'next'?\n\nThanks.\n"},{"id":"549320","messageId":"20260730180207.83197-1-diy2903@gmail.com","threadId":"66070","inReplyTo":"xmqqpl05o5n7.fsf@gitster.g","subject":"Re: [PATCH v2 2/2] t: use commit_body to extract commit message bodies","fromName":"Shlok Kulshreshtha","fromEmail":"diy2903@gmail.com","sentAt":"2026-07-30T18:02:07Z","receivedAt":"2026-07-30T18:02:13Z","isPatch":true,"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> I would not claim to have checked all of these changes, but I did\n> spot check a handful and they all looked reasonable.\n>\n> Shall we mark the topic for 'next'?\n\nYes, please.\n\nTo save you reading all 66 hunks: 63 of them are the same local swap,\nwhere the rev and the output file are unchanged and only the spelling\ndiffers.\n\n\t-git cat-file commit HEAD | sed -e \"1,/^\\$/d\" >actual\n\t+commit_body HEAD >actual\n\nEach one can be confirmed by looking at the hunk alone.\n\nThe three hunks that are worth actual attention are:\n\n* t7509-commit-authorship.sh, the hunk at author_header().  This one\n  deletes the file's local message_body() helper rather than\n  substituting anything; its call sites become commit_body elsewhere in\n  the file.\n\n* t7600-merge.sh, \"merge --no-ff --edit\".  The test grepped the raw\n  commit object for a phrase and then stripped the header for the\n  comparison.  The phrase is in the body rather than the header, so the\n  grep now runs against the already-stripped body and both steps share\n  one commit_body call.\n\n* t3900-i18n-commit.sh, in test_commit_autosquash_multi_encoding().\n  The stripped body was piped into \"iconv\".  Piping commit_body into\n  \"iconv\" would reintroduce the exit-code hole,\n  so the body is written to a file and \"iconv\"\n  reads the file.\n\nEverything else in the patch is the swap above.\n"},{"id":"549321","messageId":"xmqqy0esjmj5.fsf@gitster.g","threadId":"66070","inReplyTo":"20260730180207.83197-1-diy2903@gmail.com","subject":"Re: [PATCH v2 2/2] t: use commit_body to extract commit message bodies","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-07-30T19:38:22Z","receivedAt":"2026-07-30T19:38:35Z","isPatch":true,"body":"Shlok Kulshreshtha <diy2903@gmail.com> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> I would not claim to have checked all of these changes, but I did\n>> spot check a handful and they all looked reasonable.\n>>\n>> Shall we mark the topic for 'next'?\n>\n> Yes, please.\n\nThe qutestion was not quite for you, but for those other people who\nare reading the list from sidelines.  We all know that the original\nauthor of the patch wants their work in, so that does not work as a\nuseful signal.\n\n> * t7600-merge.sh, \"merge --no-ff --edit\".  The test grepped the raw\n>   commit object for a phrase and then stripped the header for the\n>   comparison.  The phrase is in the body rather than the header, so the\n>   grep now runs against the already-stripped body and both steps share\n>   one commit_body call.\n>\n> * t3900-i18n-commit.sh, in test_commit_autosquash_multi_encoding().\n>   The stripped body was piped into \"iconv\".  Piping commit_body into\n>   \"iconv\" would reintroduce the exit-code hole,\n>   so the body is written to a file and \"iconv\"\n>   reads the file.\n\nThese are as the log message describes ;-)  All looked good.\n\nThanks.\n"}]}