git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: Mathias Rav <m@git.strova.dk>, git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	Phillip Wood <phillip.wood@dunelm.org.uk>,
	Karthik Nayak <karthik.188@gmail.com>
Subject: Re: [PATCH] rebase -i: use same commit's message and date with f -C
Date: Tue, 23 Sep 2025 16:23:47 +0100	[thread overview]
Message-ID: <1635b82d-a3aa-4b83-8d7b-e415945dbd2e@gmail.com> (raw)
In-Reply-To: <92d4d585-09e9-4f1d-a471-1ad6b312fa61@app.fastmail.com>

Hi Mathias

On 23/09/2025 09:55, Mathias Rav wrote:
> In `git rebase -i` with the fixup command, the -C flag controls whether
> the commit message is taken from the previous or current commit,
> but currently the author name, email and date are always taken from the
> previous commit. The fixup command is used to squash two commits where
> one commit has a good message and the other's message does not matter,
> and it is usually also the case that the commit with the good message
> is the one that has the good authorship information; the other is a
> fixup commit that was presumably made by the user moments ago, whereas
> the commit with the good message is the one whose date should be kept.
> > Most of the time, a fixup commit is made on top of the commit to be
> fixed up, in which case the rebase -i fixup command is used without -C.
> The fixup -C case arises when an earlier commit in the branch is split,
> leaving part of the commit to be squashed into a later commit, in which
> case fixup -C would be expected to keep the date on the later commit,
> and discard the author date of the ephemeral newly split commit.

In that case I'd manually squash the later commit into the split commit 
as I don't think you cannot use "rebase --autosquash" to automatically 
squash a fixup commit into one of its descendants. I use "fixup -C" to 
amend and reword existing commits in the same way that I use an ordinary 
"fixup" to amend an existing commit. The only difference is that I'm 
rewording the commit message at the same time as I'm possibly changing 
the commit content. I use "fixup -C" to expanding the commit message, or 
fix typos and want to keep the original commit's authorship as I would 
do if I was not changing the commit message.

I think the difference here is that the design of the "fixup" and 
"squash" commands assumes that they are fixing up an ancestor, not a 
descendant.

Thanks

Phillip
> Change the behavior so that fixup with -C takes both message and author
> from the current commit, instead of taking the author from the previous.
> 
> Tweak try_to_commit to allow specifying author in addition to AMEND_MSG,
> and pass author from the current commit in do_pick_commit in `f -C`.
> 
> Tweak the help text in `git rebase -i` to reflect the changed behavior.
> 
> Add a test that ensures that the author metadata for the second current
> commit is kept, and remove some author metadata checks from other tests
> that now fail since the author metadata is different (as intended).
> 
> Signed-off-by: Mathias Rav <m@git.strova.dk>
> ---
> 
> I described my own workflow for fixup -C above,
> and it's the only use of fixup -C I'm aware of.
> 
> If the current behavior of keeping message from one
> and author from another is useful in someone else's
> workflow, then I'm happy to be enlightened.
> 
> Correct author dates are certainly more nice-to-have
> than need-to-have in most git workflows, but I think
> it's worthwhile to have git go the extra mile here.
> 
>   rebase-interactive.c            |  4 ++--
>   sequencer.c                     |  5 +++--
>   t/t3437-rebase-fixup-options.sh | 15 ++++++++++-----
>   3 files changed, 15 insertions(+), 9 deletions(-)
> 
> diff --git a/rebase-interactive.c b/rebase-interactive.c
> index 809f76a87b..dd303168c2 100644
> --- a/rebase-interactive.c
> +++ b/rebase-interactive.c
> @@ -53,8 +53,8 @@ void append_todo_help(int command_count,
>   "s, squash <commit> = use commit, but meld into previous commit\n"
>   "f, fixup [-C | -c] <commit> = like \"squash\" but keep only the previous\n"
>   "                   commit's log message, unless -C is used, in which case\n"
> -"                   keep only this commit's message; -c is same as -C but\n"
> -"                   opens the editor\n"
> +"                   keep this commit's message and date; -c is same as -C\n"
> +"                   but opens the editor\n"
>   "x, exec <command> = run command (the rest of the line) using shell\n"
>   "b, break = stop here (continue rebase later with 'git rebase --continue')\n"
>   "d, drop <commit> = remove commit\n"
> diff --git a/sequencer.c b/sequencer.c
> index aaf2e4df64..80209b6b07 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -1560,7 +1560,8 @@ static int try_to_commit(struct repository *r,
>   			strbuf_addstr(msg, orig_message);
>   			hook_commit = "HEAD";
>   		}
> -		author = amend_author = get_author(message);
> +		if (!author)
> +			author = amend_author = get_author(message);
>   		repo_unuse_commit_buffer(r, current_head,
>   					 message);
>   		if (!author) {
> @@ -2419,7 +2420,7 @@ static int do_pick_commit(struct repository *r,
>   			strbuf_addstr(&ctx->message, oid_to_hex(&commit->object.oid));
>   			strbuf_addstr(&ctx->message, ")\n");
>   		}
> -		if (!is_fixup(command))
> +		if (is_fixup_flag(command, item->flags) || !is_fixup(command))
>   			author = get_author(msg.message);
>   	}
>   	ctx->have_message = 1;
> diff --git a/t/t3437-rebase-fixup-options.sh b/t/t3437-rebase-fixup-options.sh
> index 5d306a4769..2361d3fb78 100755
> --- a/t/t3437-rebase-fixup-options.sh
> +++ b/t/t3437-rebase-fixup-options.sh
> @@ -85,6 +85,15 @@ test_expect_success 'simple fixup -C works' '
>   	test_commit_message HEAD -m "A2"
>   '
>   
> +test_expect_success 'fixup -C keeps second commit date' '
> +	test_when_finished "test_might_fail git rebase --abort" &&
> +	git checkout --detach A2 &&
> +	get_author HEAD >expect &&
> +	FAKE_LINES="1 fixup_-C 2" git rebase -i B &&
> +	get_author HEAD >actual &&
> +	test_cmp expect actual
> +'
> +
>   test_expect_success 'simple fixup -c works' '
>   	test_when_finished "test_might_fail git rebase --abort" &&
>   	git checkout --detach A2 &&
> @@ -105,9 +114,7 @@ test_expect_success 'fixup -C removes amend! from message' '
>   	FAKE_LINES="1 fixup_-C 2" git rebase -i A &&
>   	test_cmp_rev HEAD^ A &&
>   	test_cmp_rev HEAD^{tree} A1^{tree} &&
> -	test_commit_message HEAD expected-message &&
> -	get_author HEAD >actual-author &&
> -	test_cmp expected-author actual-author
> +	test_commit_message HEAD expected-message
>   '
>   
>   test_expect_success 'fixup -C with conflicts gives correct message' '
> @@ -181,8 +188,6 @@ test_expect_success 'multiple fixup -c opens editor once' '
>   		EXPECT_HEADER_COUNT=4 \
>   		git rebase -i A &&
>   	test_cmp_rev HEAD^ A &&
> -	get_author HEAD >actual-author &&
> -	test_cmp expected-author actual-author &&
>   	test_commit_message HEAD expected-message
>   '
>   


  parent reply	other threads:[~2025-09-23 15:23 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-23  8:55 [PATCH] rebase -i: use same commit's message and date with f -C Mathias Rav
2025-09-23  9:21 ` Karthik Nayak
2025-09-23 15:23 ` Phillip Wood [this message]
2025-09-23 17:10 ` Ben Knoble
2025-09-23 17:37 ` Kristoffer Haugsbakk
2025-09-23 21:38 ` Junio C Hamano
2025-09-24  8:47   ` Johannes Sixt
2025-09-24 13:48     ` Phillip Wood
2025-09-24 15:21     ` Mathias Rav
2025-09-25 10:11       ` Phillip Wood
2025-09-25 17:08         ` Junio C Hamano
2025-09-24 16:54 ` Oswald Buddenhagen
2025-09-24 20:48   ` Junio C Hamano
2025-09-25 10:08     ` Phillip Wood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1635b82d-a3aa-4b83-8d7b-e415945dbd2e@gmail.com \
    --to=phillip.wood123@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=karthik.188@gmail.com \
    --cc=m@git.strova.dk \
    --cc=phillip.wood@dunelm.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).