Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the git rebase HEAD~3 --autosquash does not squash the fixup?

Tags:

git

enter image description here

After running git rebase HEAD~3 --autosquash nothing changes... Why?

like image 425
Wynell Avatar asked Nov 04 '25 05:11

Wynell


2 Answers

Be sure to use the -i option with --autosquash. New versions of Git might not require it, but older ones will (and it doesn't hurt).

As to your comment: rebase is complicated.

In particular, git rebase is a front end that parses options and other arguments and then invokes one of several different rebase implementations:

  • git-rebase--am is the original rebase, dating back to well before even the oldest current Git versions still in use (1.7-era). It uses git format-patch and git am and is the least capable (but fastest) rebase.

  • git-rebase--interactive is the standard backend for all interactive rebases up until Git version 2.13. It uses git cherry-pick.

  • git-rebase--merge is a variant of non-interactive rebase that uses cherry-pick. This is the form of rebase you get with git rebase -m, git rebase -s strategy, or git rebase -X eXtended-argument, unless you add an explicit -i as well, in which case you get the interactive back end.

  • git-rebase--preserve-merges is a special purpose back end split off in Git version 2.19.0. It implements the old style git rebase -p. (The new git rebase -r requires the new sequencer-based rebase mentioned below.)

  • Starting with Git 2.13 and progressing further through Git 2.19 (when the preserve-merges back end was split off), the interactive rebase backend has grown more capable (and been written less in shell script and more in C), and now uses Git's sequencer code, which previously mainly implemented git cherry-pick and git revert.

  • As of Git 2.20, git-rebase--interactive no longer exists at all (but git rebase -i still does an interactive rebase). As of Git 2.23, git-rebase--am no longer exists as a separate back-end script (but this style of rebase still exists, it's just handled more directly).

  • As of Git 2.26, git rebase no longer uses the am style machinery by default. (This might mean you don't need a separate -i option, but my own Git installations are not this new so I have not tested it.)

The --autosquash option requires the use of the interactive back end machinery, and requires that Git generate the list of commits that might be applied so that the code can check for fixup! and squash! commit subjects. Use of the interactive machinery in particular disables the "already up to date" check.

like image 139
torek Avatar answered Nov 07 '25 02:11

torek


2020:

Be sure to use the -i option with --autosquash

2023:

Not anymore! With Git 2.44 (Q1 2024), "git rebase --autosquash"(man) is now enabled for non-interactive rebase, but it is still incompatible with the apply backend.

See commit cb00f52, commit 297be59, commit 75cf39b (14 Nov 2023) by Andy Koppe (akoppecodek).
(Merged by Junio C Hamano -- gitster -- in commit f8f87e0, 09 Dec 2023)

rebase: support --autosquash without -i

Signed-off-by: Andy Koppe

The rebase --autosquash(man) option is quietly ignored when used without --interactive (apart from preventing preemptive fast-forwarding and triggering conflicts with apply backend options).

Change that to support --autosquash without --interactive, by dropping its restriction to REBASE_INTERACTIVE_EXCPLICIT mode.
When used this way, auto-squashing is done without opening the todo list editor.

Drop the -i requirement from the --autosquash description.

And:

rebase: rewrite --(no-)autosquash documentation

Signed-off-by: Andy Koppe

Rewrite the description of the rebase --(no-)autosquash options to try to make it a bit clearer.
Don't use "the '...'" to refer to part of a commit message, mention how --interactive can be used to review the todo list, and add a bit more detail on commit --squash/amend.

git rebase now includes in its man page:

Automatically squash commits with specially formatted messages into previous commits being rebased.
If a commit message starts with "squash! ", "fixup! " or "amend! ", the remainder of the subject line is taken as a commit specifier, which matches a previous commit if it matches the subject line or the hash of that commit.
If no commit matches fully, matches of the specifier with the start of commit subjects are considered.

In the rebase todo list, the actions of squash, fixup and amend commits are changed from pick to squash, fixup or fixup -C, respectively, and they are moved right after the commit they modify.
The --interactive option can be used to review and edit the todo list before proceeding.

The recommended way to create commits with squash markers is by using the --squash, --fixup, --fixup=amend: or --fixup=reword: options of git commit, which take the target commit as an argument and automatically fill in the subject line of the new commit from that.

Settting configuration variable rebase.autoSquash to true enables auto-squashing by default for interactive rebase.
The --no-autosquash option can be used to override that setting.

like image 35
VonC Avatar answered Nov 07 '25 01:11

VonC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!