8

I've been reading git documentation on commit and rebase, but I still don't understand the difference between using fixup! or squash! as a prefix for the commit message when doing a rebase --autosquash. I believe I understand what fixup! does in terms of fixing previous commits, but I fail to see a good example where squash! is used instead. Can anyone clarify the difference between the two and give some context where they would be used differently? Thanks in advance!

  • 1
    Would the second part of my old answer http://stackoverflow.com/a/2302947/6309 provide a decent example of `squash!` usage? – VonC Aug 31 '16 at 14:59
  • @VonC It took me a while to absorb, but yes! This answers my question. And just to be sure I understand, using `squash!` will guarantee that the squashing operation is recorded in the history, which is unlike `fixup!` where the squash operation is invisible for a more "cleaner" approach. Correct? –  Aug 31 '16 at 15:14
  • Yes, that is the gist of it. I have added an answer to extract from my older (and way too long) answer what is interesting here. – VonC Aug 31 '16 at 15:23

1 Answers1

8

As I illustrated in "Trimming Git Commits/Squashing Git History", and to summarize:

with the fixup! directive, you could keep that squashing "invisible" in the commit message, while still benefiting from the automatic commit reordering with the --autosquash option

As the Op Dash comments:

Using squash! will guarantee that the squashing operation is recorded in the history, which is unlike fixup! where the squash operation is invisible for a more "cleaner" approach.


Another difference, before Git 2.16.x/2.17 (Q1 2018), is that you could not combined "git commit --fixup" with an additional commit message.
This is now no longer the case.

See commit 30884c9 (22 Dec 2017) by Ævar Arnfjörð Bjarmason (avar).
Helped-by: Eric Sunshine (sunshineco).
(Merged by Ævar Arnfjörð Bjarmason -- avar -- in commit 30884c9, 22 Dec 2017)

commit: add support for --fixup <commit> -m"<extra message>"

Add support for supplying the -m option with --fixup.
Doing so has errored out ("Option -m cannot be combined") ever since --fixup was introduced.
Before this, the only way to amend the fixup message while committing was to use --edit and amend it in the editor.

The use-case for this feature is one of:

  • Leaving a quick note to self when creating a --fixup commit when it's not self-evident why the commit should be squashed without a note into another one.

  • (Ab)using the --fixup feature to "fix up" commits that have already been pushed to a branch that doesn't allow non-fast-forwards,
    i.e. just noting "this should have been part of that other commit", and if the history ever got rewritten in the future the two should be combined.

In such a case you might want to leave a small message,
e.g. "forgot this part, which broke XYZ".


Note that before Git 2.17 (Q2 2018) "git commit --fixup" did not allow "-m<message>" option to be used at the same time; allow it to annotate resulting commit with more text.

See commit 30884c9, commit f55e84f (22 Dec 2017) by Ævar Arnfjörð Bjarmason (avar).
Helped-by: Eric Sunshine (sunshineco).
(Merged by Junio C Hamano -- gitster -- in commit c1ab3b8, 27 Feb 2018)

commit: add support for --fixup <commit> -m"<extra message>"

Add support for supplying the -m option with --fixup. Doing so has errored out ever since --fixup was introduced. Before this, the only way to amend the fixup message while committing was to use --edit and amend it in the editor.

The use-case for this feature is one of:

  • Leaving a quick note to self when creating a --fixup commit when it's not self-evident why the commit should be squashed without a note into another one.

  • (Ab)using the --fixup feature to "fix up" commits that have already been pushed to a branch that doesn't allow non-fast-forwards, i.e. just noting "this should have been part of that other commit", and if the history ever got rewritten in the future the two should be combined.

    In such a case you might want to leave a small message, e.g. "forgot this part, which broke XYZ".

With this, --fixup <commit> -m"More" -m"Details" will result in a commit message like:

!fixup <subject of <commit>>

More

Details

When the --fixup option was initially added the "Option -m cannot be combined" error was expanded from -c, -C and -F to also include --fixup (commit d71b8ba, "commit: --fixup option for use with rebase --autosquash", 2010-11-02, Git 1.7.4-rc0)).

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250