{"thread":{"id":"63266","subject":"[PATCH] [RFC] rebase -m: partial support for copying extra commit headers","startedAt":"2025-04-07T15:52:48Z","lastAt":"2025-04-09T15:36:19Z","messageCount":6,"participants":["Phillip Wood via GitGitGadget","brian m. carlson","Phillip Wood","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"515782","messageId":"pull.1902.git.1744041163929.gitgitgadget@gmail.com","threadId":"63266","inReplyTo":null,"subject":"[PATCH] [RFC] rebase -m: partial support for copying extra commit headers","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-04-07T15:52:43Z","receivedAt":"2025-04-07T15:52:48Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThere are external projects such as GitButler that add extra headers to\nthe commit objects that they create. Unfortunately these headers are\nlost when the user runs \"git rebase\". In the absence of merge conflicts\ncopying these headers across to the rebased commit is relatively\nstraight forward as the sequencer creates the rebased commits using\ncommit_tree_extended() rather than forking \"git commit\". Preserving them\nin the presence of merge conflict would mean that we either need to add\na way to creating extra headers when running \"git commit\" or modifying\nthe sequencer to stop using git commit when the commit message needs to\nbe edited. Both of these options involve a significant amount of more\nwork.\n\nWhile losing the extra headers if there are merge conflicts is a\nsignificant shortcoming for users rebasing their branches it is not such\na problem on the server where forges typically reject a rebase if it has\nconflicts. Therefore even though this commit is far from a complete\nsolution it is a significant improvement for forges that have not yet\nmoved to using \"git replay\" which already preserves extra commit\nheaders.\n\nIn the long run we would also want to preserve extra headers when\ncherry-picking a commit. As we cannot currently preserve extra headers\nwhen the user wishes to edit the commit message of the cherry-picked\ncommit this patch only changes the behavior of \"git rebase\"\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n    [RFC] rebase -m: partial support for copying extra commit headers\n    \n    This patch is largely a response to\n    https://lore.kernel.org/git/Z-5rpWKAVPmz32jC@pks.im/ . I'm in two minds\n    about whether we should consider merging such partial support but if it\n    helps forges preserve extra commit headers then it may well be worth it.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1902%2Fphillipwood%2Frebase-preserve-extra-commit-headers-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1902/phillipwood/rebase-preserve-extra-commit-headers-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1902\n\n sequencer.c                   | 25 +++++++++++++-----\n t/t3404-rebase-interactive.sh | 48 +++++++++++++++++++++++++++++++++++\n 2 files changed, 66 insertions(+), 7 deletions(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex ad0ab75c8d4..5b92f77b660 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1527,6 +1527,9 @@ static int parse_head(struct repository *r, struct commit **head)\n \treturn 0;\n }\n \n+/* Headers to exclude when copying extra commit headers */\n+static const char *exclude_gpgsig[] = { \"gpgsig\", \"gpgsig-sha256\", NULL };\n+\n /*\n  * Try to commit without forking 'git commit'. In some cases we need\n  * to run 'git commit' to display an error message\n@@ -1538,6 +1541,7 @@ static int parse_head(struct repository *r, struct commit **head)\n  */\n static int try_to_commit(struct repository *r,\n \t\t\t struct strbuf *msg, const char *author,\n+\t\t\t struct commit_extra_header *extra_header,\n \t\t\t struct replay_opts *opts, unsigned int flags,\n \t\t\t struct object_id *oid)\n {\n@@ -1545,7 +1549,7 @@ static int try_to_commit(struct repository *r,\n \tstruct object_id tree;\n \tstruct commit *current_head = NULL;\n \tstruct commit_list *parents = NULL;\n-\tstruct commit_extra_header *extra = NULL;\n+\tstruct commit_extra_header *extra = extra_header;\n \tstruct strbuf err = STRBUF_INIT;\n \tstruct strbuf commit_msg = STRBUF_INIT;\n \tchar *amend_author = NULL;\n@@ -1561,7 +1565,6 @@ static int try_to_commit(struct repository *r,\n \t\treturn -1;\n \n \tif (flags & AMEND_MSG) {\n-\t\tconst char *exclude_gpgsig[] = { \"gpgsig\", \"gpgsig-sha256\", NULL };\n \t\tconst char *out_enc = get_commit_output_encoding();\n \t\tconst char *message = repo_logmsg_reencode(r, current_head,\n \t\t\t\t\t\t\t   NULL, out_enc);\n@@ -1714,7 +1717,8 @@ static int try_to_commit(struct repository *r,\n \t\tcommit_post_rewrite(r, current_head, oid);\n \n out:\n-\tfree_commit_extra_headers(extra);\n+\tif (extra != extra_header)\n+\t\tfree_commit_extra_headers(extra);\n \tfree_commit_list(parents);\n \tstrbuf_release(&err);\n \tstrbuf_release(&commit_msg);\n@@ -1734,6 +1738,7 @@ static int write_rebase_head(struct object_id *oid)\n \n static int do_commit(struct repository *r,\n \t\t     const char *msg_file, const char *author,\n+\t\t     struct commit_extra_header *extra_header,\n \t\t     struct replay_opts *opts, unsigned int flags,\n \t\t     struct object_id *oid)\n {\n@@ -1749,7 +1754,7 @@ static int do_commit(struct repository *r,\n \t\t\t\t\t   msg_file);\n \n \t\tres = try_to_commit(r, msg_file ? &sb : NULL,\n-\t\t\t\t    author, opts, flags, &oid);\n+\t\t\t\t    author, extra_header, opts, flags, &oid);\n \t\tstrbuf_release(&sb);\n \t\tif (!res) {\n \t\t\trefs_delete_ref(get_main_ref_store(r), \"\",\n@@ -2251,6 +2256,7 @@ static int do_pick_commit(struct repository *r,\n \tint res, unborn = 0, reword = 0, allow, drop_commit;\n \tenum todo_command command = item->command;\n \tstruct commit *commit = item->commit;\n+\tstruct commit_extra_header *extra_header = NULL;\n \n \tif (opts->no_commit) {\n \t\t/*\n@@ -2391,8 +2397,12 @@ static int do_pick_commit(struct repository *r,\n \t\t\tstrbuf_addstr(&ctx->message, oid_to_hex(&commit->object.oid));\n \t\t\tstrbuf_addstr(&ctx->message, \")\\n\");\n \t\t}\n-\t\tif (!is_fixup(command))\n+\t\tif (!is_fixup(command)) {\n \t\t\tauthor = get_author(msg.message);\n+\t\t\tif (is_rebase_i(opts))\n+\t\t\t\textra_header = read_commit_extra_headers(commit,\n+\t\t\t\t\t\t\t\texclude_gpgsig);\n+\t\t}\n \t}\n \tctx->have_message = 1;\n \n@@ -2503,8 +2513,8 @@ static int do_pick_commit(struct repository *r,\n \t} /* else allow == 0 and there's nothing special to do */\n \tif (!opts->no_commit && !drop_commit) {\n \t\tif (author || command == TODO_REVERT || (flags & AMEND_MSG))\n-\t\t\tres = do_commit(r, msg_file, author, opts, flags,\n-\t\t\t\t\tcommit? &commit->object.oid : NULL);\n+\t\t\tres = do_commit(r, msg_file, author, extra_header, opts,\n+\t\t\t\t\tflags, commit? &commit->object.oid : NULL);\n \t\telse\n \t\t\tres = error(_(\"unable to parse commit author\"));\n \t\t*check_todo = !!(flags & EDIT_MSG);\n@@ -2535,6 +2545,7 @@ fast_forward_edit:\n leave:\n \tfree_message(commit, &msg);\n \tfree(author);\n+\tfree_commit_extra_headers(extra_header);\n \tupdate_abort_safety_file();\n \n \treturn res;\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 2aee9789a2f..200f55824c7 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -2297,6 +2297,54 @@ test_expect_success 'non-merge commands reject merge commits' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'unconflicted pick copies extra commit headers' '\n+\ttree=\"$(git rev-parse C^{tree})\" &&\n+\tparent=\"$(git rev-parse C^{commit})\" &&\n+\tfor i in 1 2 3 4 5 6 7\n+\tdo\n+\t\tcat >commit <<-EOF &&\n+\t\ttree $tree\n+\t\tparent $parent\n+\t\tauthor $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE\n+\t\tcommitter $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE\n+\t\tx-extra-header value $i\n+\n+\t\tAn empty commit with an extra header $i\n+\t\tEOF\n+\n+\t\tparent=\"$(git hash-object -t commit -w commit)\" &&\n+\t\teval \"oid$i=\\$parent\" &&\n+\t\ttest_tick || return 1\n+\tdone &&\n+\n+\tcat >todo <<-EOF &&\n+\tpick $oid1\n+\tpick $oid2\n+\tfixup $oid3\n+\treword $oid4\n+\tedit $oid5\n+\tpick $oid6\n+\tsquash $oid7\n+\tEOF\n+\n+\t(\n+\t\tset_replace_editor todo &&\n+\t\tFAKE_COMMIT_AMEND=EDITED git rebase -i --onto A $oid1^ $oid5\n+\t) &&\n+\techo changed >file2 &&\n+\tgit add file2 &&\n+\tFAKE_COMMIT_AMEND=EDITED git rebase --continue &&\n+\tj=4 &&\n+\tfor i in 1 2 4 5 6\n+\tdo\n+\t\tgit cat-file commit HEAD~$j >actual &&\n+\t\tsed -n -e /^\\$/q -e /^x-extra/p actual >actual.extra-header &&\n+\t\techo \"x-extra-header value $i\" >expect &&\n+\t\ttest_cmp expect actual.extra-header &&\n+\t\tj=$((j-1)) || return 1\n+\tdone\n+'\n+\n # This must be the last test in this file\n test_expect_success '$EDITOR and friends are unchanged' '\n \ttest_editor_unchanged\n\nbase-commit: a36e024e989f4d35f35987a60e3af8022cac3420\n-- \ngitgitgadget\n"},{"id":"515816","messageId":"Z_R6W_yjJEYuWo0A@tapette.crustytoothpaste.net","threadId":"63266","inReplyTo":"pull.1902.git.1744041163929.gitgitgadget@gmail.com","subject":"Re: [PATCH] [RFC] rebase -m: partial support for copying extra commit headers","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2025-04-08T01:22:35Z","receivedAt":"2025-04-08T01:22:43Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2025-04-07 at 15:52:43, Phillip Wood via GitGitGadget wrote:\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n> \n>     [RFC] rebase -m: partial support for copying extra commit headers\n>     \n>     This patch is largely a response to\n>     https://lore.kernel.org/git/Z-5rpWKAVPmz32jC@pks.im/ . I'm in two minds\n>     about whether we should consider merging such partial support but if it\n>     helps forges preserve extra commit headers then it may well be worth it.\n\nI'd like to see command-line options to control this and ideally a\nconfiguration option.  Right now, we know nothing about these extra\nheaders, including an expected format.  If a future version of Git (say,\n3.0) adds a new header and the user includes invalid data in this extra\nheader (which happens all the time with author and committer\ninformation), then 2.50 will propagate it on rebase and it won't be\nfixed until the user uses a version of Git that understands the header\nand can fsck it correctly.  That's not really great, since it means we\ncan unknowingly spread corruption.\n\nI am pretty sure that at $DAYJOB we'll need to have a discussion about\nwhether we want to propagate these headers during rebase and I'm\npersonally leaning against it.\n\nWhy, you ask?  I've seen at least the following types of corruption:\n\n* Missing timezones\n* Timezones with less than four digits\n* Valid timezones padded to more than four digits with zeros\n* Timezones which don't exist and never have (e.g., +1700)\n* Timezones which are so absurdly large that they push the date to a\n  year when nobody alive now will still be living\n* Date stamps that are larger than 2^64\n* Date stamps which are smaller than 2^64 but beyond the expected life\n  of the Sun\n* Extra angle brackets in the email field\n* Nothing in between the email brackets\n* Nothing before the email brackets (no name at all)\n* Names which are not UTF-8 but without an encoding header\n* Names which are not valid in the specified encoding\n* Emails which are not valid UTF-8[0]\n* Emails which don't meet the (ludicrously generous to the point of\n  being nearly unparseable) RFC production\n* Encodings which are not valid IANA charsets\n* Messages with no body and no blank line (just the newline at the end\n  of the final header)\n* gpgsig headers that include random non-ASCII bytes and control\n  characters[1]\n\nNote that all of these must be parsed in some meaningful way because\nusers don't want their forge to serve them a 500 despite them having\nsent wildly invalid data.  I encountered these during part of our\ntransition from Rugged to Git (reftable, SHA-256) and they definitely\nadded a lot of interesting complications (plus the need for lots of\ntests).\n\nConsidering that writing valid data should not be that hard[2] (and\nshould definitely be a priority) but apparently is for many people, I'm\nvery wary of us propagating headers we're not ready to fsck and I'd like\nto have an out for users and forges who would like to be a little more\ncareful.\n\nWith those constraints, I'm not totally opposed in principle to this\nfeature.\n\nI see Patrick is CC'd here and I'm interested in his thoughts, as well\nas, of course, those of anyone else as well.\n\n[0] SMTPUTF8 (RFC 6531 et al.) specifies that mailbox names may now\ncontain UTF-8.  For instance, you can email 🔵 at this domain and it\nwill be delivered to me.\n[1] It should be noted that all of our signing implementations produce\nonly non-control printable ASCII characters plus newline.\n[2] Maybe I am being unfair or unduly harsh to implementers, but I do at\nleast agree with the half of Postel's Law that says that one should be\nconservative with what one generates and I would hope others do as well.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"515848","messageId":"240d1cab-b564-45ae-945e-cba621aa7562@gmail.com","threadId":"63266","inReplyTo":"Z_R6W_yjJEYuWo0A@tapette.crustytoothpaste.net","subject":"Re: [PATCH] [RFC] rebase -m: partial support for copying extra commit headers","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-04-08T10:15:56Z","receivedAt":"2025-04-08T10:16:01Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi brian\n\nOn 08/04/2025 02:22, brian m. carlson wrote:\n> On 2025-04-07 at 15:52:43, Phillip Wood via GitGitGadget wrote:\n>> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>>\n>>      [RFC] rebase -m: partial support for copying extra commit headers\n>>      \n>>      This patch is largely a response to\n>>      https://lore.kernel.org/git/Z-5rpWKAVPmz32jC@pks.im/ . I'm in two minds\n>>      about whether we should consider merging such partial support but if it\n>>      helps forges preserve extra commit headers then it may well be worth it.\n> \n> I'd like to see command-line options to control this and ideally a\n> configuration option.  Right now, we know nothing about these extra\n> headers, including an expected format.  If a future version of Git (say,\n> 3.0) adds a new header and the user includes invalid data in this extra\n> header (which happens all the time with author and committer\n> information), then 2.50 will propagate it on rebase and it won't be\n> fixed until the user uses a version of Git that understands the header\n> and can fsck it correctly.  That's not really great, since it means we\n> can unknowingly spread corruption.\n\nWe could certainly add some way to make this opt-in if there is a desire \nfor it and you make a good point about compatibility if we add a new \ncommit header. I'm not sure I'd describe preserving these headers when \nrebasing as spreading corruption though as we're simply rewriting \nexisting commits. If the user chose to merge rather than rebase we'd \nstill have the same issues without creating any new commits.\n\n> I am pretty sure that at $DAYJOB we'll need to have a discussion about\n> whether we want to propagate these headers during rebase and I'm\n> personally leaning against it.\n\nMy understanding is that GitHub has been using \"git replay\" for rebases \nand therefore copying extra commit headers since the middle of 2023 \n[1,2]. The message I linked to in my original mail suggests that the \n\"change-id\" header is preserved when rebasing on GitHub.\n\n> Why, you ask?  I've seen at least the following types of corruption:\n> \n> * Missing timezones\n> * Timezones with less than four digits\n> * Valid timezones padded to more than four digits with zeros\n> * Timezones which don't exist and never have (e.g., +1700)\n> * Timezones which are so absurdly large that they push the date to a\n>    year when nobody alive now will still be living\n> * Date stamps that are larger than 2^64\n> * Date stamps which are smaller than 2^64 but beyond the expected life\n>    of the Sun\n> * Extra angle brackets in the email field\n> * Nothing in between the email brackets\n> * Nothing before the email brackets (no name at all)\n> * Names which are not UTF-8 but without an encoding header\n> * Names which are not valid in the specified encoding\n> * Emails which are not valid UTF-8[0]\n> * Emails which don't meet the (ludicrously generous to the point of\n>    being nearly unparseable) RFC production\n> * Encodings which are not valid IANA charsets\n> * Messages with no body and no blank line (just the newline at the end\n>    of the final header)\n> * gpgsig headers that include random non-ASCII bytes and control\n>    characters[1]\n\nThanks for sharing that, it is an interesting list. On the subject of \nencoding I do think our documentation could be clearer that the encoding \napplies to all the headers as well as the commit message. As far as I \ncan see it only mentions the commit message, not the author or committer \nidentities but repo_logmsg_reencode() re-encodes the whole commit \nbuffer. Out of interest do you think we could be doing a better job with \nfsck to pick up some of these problems earlier?\n\nI think \"git rebase\" only cares that the author identity can be parsed \nby split_ident() which is fairly lenient.\n\n> I see Patrick is CC'd here and I'm interested in his thoughts, as well\n> as, of course, those of anyone else as well.\n\nYes me too\n\nThanks for your thoughtful and intereting reply\n\nPhillip\n\n[1] \nhttps://github.blog/changelog/2023-06-28-rebase-commits-now-created-using-the-merge-ort-strategy/\n[2] \nhttps://github.blog/engineering/infrastructure/scaling-merge-ort-across-github/\n\n"},{"id":"515871","messageId":"xmqqr022yaq6.fsf@gitster.g","threadId":"63266","inReplyTo":"240d1cab-b564-45ae-945e-cba621aa7562@gmail.com","subject":"Re: [PATCH] [RFC] rebase -m: partial support for copying extra commit headers","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-04-08T14:44:01Z","receivedAt":"2025-04-08T14:44:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> Thanks for sharing that, it is an interesting list. On the subject of\n> encoding I do think our documentation could be clearer that the\n> encoding applies to all the headers as well as the commit message. As\n> far as I can see it only mentions the commit message, not the author\n> or committer identities but repo_logmsg_reencode() re-encodes the\n> whole commit buffer. Out of interest do you think we could be doing a\n> better job with fsck to pick up some of these problems earlier?\n>\n> I think \"git rebase\" only cares that the author identity can be parsed\n> by split_ident() which is fairly lenient.\n\n\"rebase\" already knows that it has to be picky which header fields\nneed to be propagated and which must not be, doesn't it?  Can the\nsame be said for arbitrary \"extra\" header fields?\n\nInformation on some of the header fields are inherently destroyed\nwhen you refine an existing commit.  The value on the 'parent'\nheaders may need to be updated (unless \"rebase\" is fast-forwarding\nan earlier part of the changes on the same base), the 'author'\ninformation usually wants to be preserved, but when the scale of the\nchange since the previous iteration is so large, you may give it a\nnew authorship, the 'committer' information should record who\ncreated the new commit object that records the result of rebasing,\nthe 'gpgsig' and 'gigsig-sha256' header fields would lose validity\nif you are creating a new object that is different from the original\nby even a single bit (if we are somehow recording which predecessor\ncommit the new one replaces, it certainly is safe to drop these that\nhave lost validity, as we can go back to the predecessor to see it\nhas a valid signature, and the change in the new commit that lost\nthe signature fields is the moral equivalent of the original.\nOtherwise, carrying a stale signature may serve as a reminder that\nthe commit was rewritten in the past---I dunno).  And so on.\n\nNow, one thing that worries me is this.  If \"extra\" commit headers\ninclude truly extra fields with unknown semantics, the machinery\ncannot tell which ones are safe and benefitial to propagate.\n\nThanks.\n"},{"id":"515914","messageId":"7f744f34-050c-4d8b-b5fc-aae622c3c5b6@gmail.com","threadId":"63266","inReplyTo":"xmqqr022yaq6.fsf@gitster.g","subject":"Re: [PATCH] [RFC] rebase -m: partial support for copying extra commit headers","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-04-09T14:11:19Z","receivedAt":"2025-04-09T14:11:32Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Junio\n\nOn 08/04/2025 15:44, Junio C Hamano wrote:\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n> \n>> Thanks for sharing that, it is an interesting list. On the subject of\n>> encoding I do think our documentation could be clearer that the\n>> encoding applies to all the headers as well as the commit message. As\n>> far as I can see it only mentions the commit message, not the author\n>> or committer identities but repo_logmsg_reencode() re-encodes the\n>> whole commit buffer. Out of interest do you think we could be doing a\n>> better job with fsck to pick up some of these problems earlier?\n>>\n>> I think \"git rebase\" only cares that the author identity can be parsed\n>> by split_ident() which is fairly lenient.\n> \n> \"rebase\" already knows that it has to be picky which header fields\n> need to be propagated and which must not be, doesn't it?\n\nI'd say it's picky because of the way it is implemented - it calls \"git \ncommit\" and there is no way to set \"extra\" header fields when doing that.\n\n>  Can the\n> same be said for arbitrary \"extra\" header fields?\n> \n> Information on some of the header fields are inherently destroyed\n> when you refine an existing commit.  The value on the 'parent'\n> headers may need to be updated (unless \"rebase\" is fast-forwarding\n> an earlier part of the changes on the same base), the 'author'\n> information usually wants to be preserved, but when the scale of the\n> change since the previous iteration is so large, you may give it a\n> new authorship, the 'committer' information should record who\n> created the new commit object that records the result of rebasing,\n> the 'gpgsig' and 'gigsig-sha256' header fields would lose validity\n> if you are creating a new object that is different from the original\n> by even a single bit (if we are somehow recording which predecessor\n> commit the new one replaces, it certainly is safe to drop these that\n> have lost validity, as we can go back to the predecessor to see it\n> has a valid signature, and the change in the new commit that lost\n> the signature fields is the moral equivalent of the original.\n> Otherwise, carrying a stale signature may serve as a reminder that\n> the commit was rewritten in the past---I dunno).  And so on.\n> \n> Now, one thing that worries me is this.  If \"extra\" commit headers\n> include truly extra fields with unknown semantics, the machinery\n> cannot tell which ones are safe and benefitial to propagate.\n\nThat's true and we could have a config key to select which \"extra\" \nheaders are propagated. We do however unconditionally propagate all \n\"extra\" headers when amending a commit with \"git commit --amend\" and \nwhen rewriting it with \"git replay\" which I think GitHub have been using \nto rebase branches for over 18 months. If we're worried about rebase \nunconditionally copying these headers we do something to stop \"git \nreplay\" doing the same. On the other hand if \"git replay\" is being used \nin the wild without problems maybe we don't need to worry.\n\nBest Wishes\n\nPhillip\n\n"},{"id":"515918","messageId":"xmqq34ehtki8.fsf@gitster.g","threadId":"63266","inReplyTo":"7f744f34-050c-4d8b-b5fc-aae622c3c5b6@gmail.com","subject":"Re: [PATCH] [RFC] rebase -m: partial support for copying extra commit headers","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-04-09T15:36:15Z","receivedAt":"2025-04-09T15:36:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> That's true and we could have a config key to select which \"extra\"\n> headers are propagated.\n\nNo, please don't.  No such config key should ever exist.\n\nIf something has a defined semantics, which all projects that use\nGit can agree on, that is solid enough to deserve to be in the\nheader part of the commit object (as opposed to one of the trailers\nwith user-defined semantics that can vary from project to project),\nthere should never be a way to give it different semantics by\ntweaking whether it is or it is not propagated when rewriting.\n"}]}