threads / discuss / 63606

Question: is there a short way to merge the last commit to the second last one?

Subject: Question: is there a short way to merge the last commit to the second last one?

## tl;dr

10 messages between Jun 8, 2025 and Jun 9, 2025.

replies: 9people: 4as markdown or json

Aditya Garg· Jun 8, 2025, 18:30 UTC · lore
Hi all
This is something I usually come across. Sometimes I make a mistake in a commit, and then I create a new commit with a correction. After that I git rebase -i and use the fixup option to make the fixup commit a part of the main commit.
I was wondering if there is a command, like git fixup or something that could make this process easier? I know about git squash but I prefer doing fixup.
Sorry If I didn't notice any docs.

Thanks Aditya

brian m. carlson· Jun 8, 2025, 18:57 UTC · re: Aditya Garg · lore

Re: Question: is there a short way to merge the last commit to the second last one?

On 2025-06-08 at 18:30:30, Aditya Garg wrote:
> Hi all
Hi,
Show 8 quoted lines
> This is something I usually come across. Sometimes I make a mistake in
> a commit, and then I create a new commit with a correction. After that
> I git rebase -i and use the fixup option to make the fixup commit a
> part of the main commit.
> 
> I was wondering if there is a command, like git fixup or something
> that could make this process easier? I know about git squash but I
> prefer doing fixup.

You are hardly the only person to have this problem. It happens to me and lots of other people very frequently and so we do have a couple ways to fix that.

If the mistake you want to fix is in the most recent commit, instead of making a new commit, you can do `git commit --amend`. That updates the last commit with the changes you've staged via `git add` and `git rm`. It also allows you to edit the message; if you don't want that, you can pass the `--no-edit` option.

The other situation is that the mistake is in an older commit. Here, we have a special variant of `git commit` that will mark the commit to be automatically fixed up. You could say something like `git commit --fixup HEAD^` (or whatever revision you like instead of `HEAD^`). Then, when you do `git rebase -i --autosquash`, it will automatically be moved to the proper location and marked for fixup.

If you want to change the commit message as well, you can replace `--fixup` with `--squash` and you'll get prompted for something you can put in the commit message. When you squash it, then you'll be prompted to merge the two commit messages (the old and new).

If your goal is to just do the fixups and squash and not anything else interactive, then you can do this:

    GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash

in a POSIX shell (that is, on macOS or Linux or under Git Bash, but not under Powershell or CMD).

The `GIT_SEQUENCE_EDITOR=true` tells Git not to edit the sequence list (also known as the todo list, which contains the pick, fixup, and squash commands) and just perform the rebase. You can see an alias for doing this at [0], which may be helpful as well.

[0] https://github.com/bk2204/dotfiles/blob/5e74a513ae133ec30b20992fb4c2f967fa6f047b/git/gitconfig#L41
-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
Aditya Garg· Jun 8, 2025, 19:09 UTC · re: brian m. carlson · lore

Re: Question: is there a short way to merge the last commit to the second last one?

On 9 June 2025 12:27:44 am IST, "brian m. carlson" <sandals@crustytoothpaste.net> wrote:
Show 24 quoted lines
>On 2025-06-08 at 18:30:30, Aditya Garg wrote:
>> Hi all
>
>Hi,
>
>> This is something I usually come across. Sometimes I make a mistake in
>> a commit, and then I create a new commit with a correction. After that
>> I git rebase -i and use the fixup option to make the fixup commit a
>> part of the main commit.
>> 
>> I was wondering if there is a command, like git fixup or something
>> that could make this process easier? I know about git squash but I
>> prefer doing fixup.
>
>You are hardly the only person to have this problem.  It happens to me
>and lots of other people very frequently and so we do have a couple ways
>to fix that.
>
>If the mistake you want to fix is in the most recent commit, instead of
>making a new commit, you can do `git commit --amend`.  That updates the
>last commit with the changes you've staged via `git add` and `git rm`.
>It also allows you to edit the message; if you don't want that, you can
>pass the `--no-edit` option.
>
This is what was searching for!
Show 26 quoted lines
>The other situation is that the mistake is in an older commit.  Here, we
>have a special variant of `git commit` that will mark the commit to be
>automatically fixed up.  You could say something like `git commit
>--fixup HEAD^` (or whatever revision you like instead of `HEAD^`). Then,
>when you do `git rebase -i --autosquash`, it will automatically be moved
>to the proper location and marked for fixup.
>
>If you want to change the commit message as well, you can replace
>`--fixup` with `--squash` and you'll get prompted for something you can
>put in the commit message.  When you squash it, then you'll be prompted
>to merge the two commit messages (the old and new).
>
>If your goal is to just do the fixups and squash and not anything else
>interactive, then you can do this:
>
>    GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
>
>in a POSIX shell (that is, on macOS or Linux or under Git Bash, but not
>under Powershell or CMD).
>
>The `GIT_SEQUENCE_EDITOR=true` tells Git not to edit the sequence list
>(also known as the todo list, which contains the pick, fixup, and squash
>commands) and just perform the rebase.  You can see an alias for doing
>this at [0], which may be helpful as well.
>
>[0] https://github.com/bk2204/dotfiles/blob/5e74a513ae133ec30b20992fb4c2f967fa6f047b/git/gitconfig#L41
Thanks a lot brian, your reply was perfect!
Phillip Wood· Jun 8, 2025, 19:31 UTC · re: brian m. carlson · lore

Re: Question: is there a short way to merge the last commit to the second last one?

On 08/06/2025 19:57, brian m. carlson wrote:
Show 5 quoted lines
> 
> If your goal is to just do the fixups and squash and not anything else
> interactive, then you can do this:
> 
>      GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
Just a quick note to say that since git v2.44.0 you can just run
	git rebase --autosquash

and it will squash any fixup commits without asking you to edit the todo list.

Also "git commit --fixup=amend:HEAD^" allows you to edit the original commit message and this new message will be used when the commit is squashed by "git rebase --autosquash"

Best Wishes
Phillip
Aditya Garg· Jun 8, 2025, 19:35 UTC · re: Phillip Wood · lore

Re: Question: is there a short way to merge the last commit to the second last one?

On 9 June 2025 1:01:19 am IST, Phillip Wood <phillip.wood123@gmail.com> wrote:
Show 11 quoted lines
>On 08/06/2025 19:57, brian m. carlson wrote:
>> 
>> If your goal is to just do the fixups and squash and not anything else
>> interactive, then you can do this:
>> 
>>      GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
>
>Just a quick note to say that since git v2.44.0 you can just run
>
>	git rebase --autosquash
>
Silly question but how does it get to know what is the fixup commit?
Show 8 quoted lines
>and it will squash any fixup commits without asking you to edit the todo list.
>
>Also "git commit --fixup=amend:HEAD^" allows you to edit the original commit message and this new message will be used when the commit is squashed by "git rebase --autosquash"
>
>Best Wishes
>
>Phillip
>
brian m. carlson· Jun 8, 2025, 21:43 UTC · re: Aditya Garg · lore

Re: Question: is there a short way to merge the last commit to the second last one?

On 2025-06-08 at 19:35:24, Aditya Garg wrote:
Show 16 quoted lines
> 
> 
> On 9 June 2025 1:01:19 am IST, Phillip Wood <phillip.wood123@gmail.com> wrote:
> >On 08/06/2025 19:57, brian m. carlson wrote:
> >> 
> >> If your goal is to just do the fixups and squash and not anything else
> >> interactive, then you can do this:
> >> 
> >>      GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
> >
> >Just a quick note to say that since git v2.44.0 you can just run
> >
> >	git rebase --autosquash
> >
> 
> Silly question but how does it get to know what is the fixup commit?

That's actually a great question. When you do `git commit --squash REVISION`, it takes the summary of the commit specified by `REVISION` and precedes it with `squash! `, and for `--fixup`, it does `fixup! `.

Then, it's just a matter of re-ordering the squash or fixup commits in order after the commit with the corresponding summary.

So with this shell script:

---- #!/bin/sh

git init --object-format=sha256 test-repo cd test-repo

echo abc >file.txt git add file.txt git commit -m 'Initial commit'

echo def >file.txt git add file.txt git commit --fixup HEAD git show ----

You get something like this:
----
Initialized empty Git repository in /tmp/user/1000/test-repo/.git/
[dev (root-commit) 7327102] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 file.txt
[dev 8bdd271] fixup! Initial commit
 1 file changed, 1 insertion(+), 1 deletion(-)
commit 8bdd271b6d4e22b7ca697c2d4499fd3e0825977d7d2c917b92e1f1f12383f52c
Author: brian m. carlson <sandals@crustytoothpaste.net>
Date:   Sun Jun 8 21:41:43 2025 +0000
    fixup! Initial commit
diff --git a/file.txt b/file.txt
index e0ef420..559afde 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1 @@
-abc
+def
----

Of course, `--autosquash` does require using `--fixup` and `--squash` or
otherwise naming the commits that way.
-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
Aditya Garg· Jun 9, 2025, 04:29 UTC · re: brian m. carlson · lore

Re: Question: is there a short way to merge the last commit to the second last one?

On 9 June 2025 3:13:01 am IST, "brian m. carlson" <sandals@crustytoothpaste.net> wrote:
Show 69 quoted lines
>On 2025-06-08 at 19:35:24, Aditya Garg wrote:
>> 
>> 
>> On 9 June 2025 1:01:19 am IST, Phillip Wood <phillip.wood123@gmail.com> wrote:
>> >On 08/06/2025 19:57, brian m. carlson wrote:
>> >> 
>> >> If your goal is to just do the fixups and squash and not anything else
>> >> interactive, then you can do this:
>> >> 
>> >>      GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
>> >
>> >Just a quick note to say that since git v2.44.0 you can just run
>> >
>> >	git rebase --autosquash
>> >
>> 
>> Silly question but how does it get to know what is the fixup commit?
>
>That's actually a great question.  When you do `git commit --squash
>REVISION`, it takes the summary of the commit specified by `REVISION`
>and precedes it with `squash! `, and for `--fixup`, it does `fixup! `.
>
>Then, it's just a matter of re-ordering the squash or fixup commits in
>order after the commit with the corresponding summary.
>
>So with this shell script:
>
>----
>#!/bin/sh
>
>git init --object-format=sha256 test-repo
>cd test-repo
>
>echo abc >file.txt
>git add file.txt
>git commit -m 'Initial commit'
>
>echo def >file.txt
>git add file.txt
>git commit --fixup HEAD
>git show
>----
>
>You get something like this:
>
>----
>Initialized empty Git repository in /tmp/user/1000/test-repo/.git/
>[dev (root-commit) 7327102] Initial commit
> 1 file changed, 1 insertion(+)
> create mode 100644 file.txt
>[dev 8bdd271] fixup! Initial commit
> 1 file changed, 1 insertion(+), 1 deletion(-)
>commit 8bdd271b6d4e22b7ca697c2d4499fd3e0825977d7d2c917b92e1f1f12383f52c
>Author: brian m. carlson <sandals@crustytoothpaste.net>
>Date:   Sun Jun 8 21:41:43 2025 +0000
>
>    fixup! Initial commit
>
>diff --git a/file.txt b/file.txt
>index e0ef420..559afde 100644
>--- a/file.txt
>+++ b/file.txt
>@@ -1 +1 @@
>-abc
>+def
>----
>
>Of course, `--autosquash` does require using `--fixup` and `--squash` or
>otherwise naming the commits that way.
Now it's clear. Thanks a lot brian and Junio!
Phillip Wood· Jun 9, 2025, 10:06 UTC · re: Phillip Wood · lore

Re: Question: is there a short way to merge the last commit to the second last one?

On 08/06/2025 20:31, Phillip Wood wrote:
Show 10 quoted lines
> On 08/06/2025 19:57, brian m. carlson wrote:
>>
>> If your goal is to just do the fixups and squash and not anything else
>> interactive, then you can do this:
>>
>>      GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
> 
> Just a quick note to say that since git v2.44.0 you can just run
> 
>      git rebase --autosquash

That will also rebase your branch if you don't specify a commit. When you're re-rolling a patch series it is normally preferred to keep the same base commit. You can do that by adding "--keep-base" to avoid rebasing onto the updated upstream branch.

Best Wishes
Phillip
Aditya Garg· Jun 9, 2025, 10:35 UTC · re: Phillip Wood · lore

Re: Question: is there a short way to merge the last commit to the second last one?

Show 13 quoted lines
> On 9 Jun 2025, at 3:34 PM, Phillip Wood <phillip.wood123@gmail.com> wrote:
> 
> On 08/06/2025 20:31, Phillip Wood wrote:
>>> On 08/06/2025 19:57, brian m. carlson wrote:
>>> 
>>> If your goal is to just do the fixups and squash and not anything else
>>> interactive, then you can do this:
>>> 
>>>      GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
>> Just a quick note to say that since git v2.44.0 you can just run
>>     git rebase --autosquash
> 
> That will also rebase your branch if you don't specify a commit. When you're re-rolling a patch series it is normally preferred to keep the same base commit. You can do that by adding "--keep-base" to avoid rebasing onto the updated upstream branch.
I'll try that. Thanks.
Junio C Hamano· Jun 8, 2025, 20:55 UTC · re: Aditya Garg · lore

Re: Question: is there a short way to merge the last commit to the second last one?

Aditya Garg <gargaditya08@live.com> writes:
Show 10 quoted lines
> Hi all
>
> This is something I usually come across. Sometimes I make a
> mistake in a commit, and then I create a new commit with a
> correction. After that I git rebase -i and use the fixup option to
> make the fixup commit a part of the main commit.
>
> I was wondering if there is a command, like git fixup or something
> that could make this process easier? I know about git squash but I
> prefer doing fixup.

If your "After that" is "immediately after that before piling any more commits on top of the history", then the standard answer would be "rebase --autosquash", i.e.

 ... work work work
 $ git commit [options and arguments]
 ... oops that needs further change
 ... work more
 $ git commit -m 'fixup' [options and arguments]
 $ git rebase --autosquash HEAD~2
But if it is truly immediately after that", then
 ... work work work
 $ git commit [options and arguments]
 ... oops that needs further change
 ... work more
 $ git commit --amend [options and arguments]
would be even simpler.

← back to recent threads