Qual é a diferença entre “squash” e “fixup” na extensão Git / Git?

111

Eu uso extensões Git há algum tempo (é incrível!), Mas não encontrei uma resposta simples para o seguinte:

Às vezes, ao digitar uma mensagem de confirmação, comete um erro de digitação. Meu amigo me mostrou como consertar da seguinte maneira (no Git Extentions):

Clique com o botão direito no commit> Advanced> Fixup commit

insira a descrição da imagem aqui

Então, eu simplesmente marque a caixa "Alterar" e reescrevo minha mensagem e pronto! Minha mensagem de confirmação foi corrigida.

Porém essa outra opção "Squash commit" ... Sempre me perguntei o que ela faz ?!

Minha pergunta é:

Alguém simplesmente me explicaria qual é a diferença exata entre o commit do Squash e o commit do Fixup nas extensões Git / Git ? Eles parecem meio ... "semelhantes" a mim: insira a descrição da imagem aqui insira a descrição da imagem aqui

Placeholder
fonte

Respostas:

153

Eu não sei o que Git Extensions faz com ele especificamente, mas git rebasetem uma opção de esmagar automaticamente ou corrigir commits com squash! ou conserto! prefixos, respectivamente:

   --autosquash, --no-autosquash
       When the commit log message begins with "squash! ..." (or "fixup!
       ..."), and there is a commit whose title begins with the same ...,
       automatically modify the todo list of rebase -i so that the commit
       marked for squashing comes right after the commit to be modified,
       and change the action of the moved commit from pick to squash (or
       fixup).

A diferença entre squash e fixup é que durante o rebase, a squashoperação solicitará que você combine as mensagens do commit original e do squash, enquanto a fixupoperação manterá a mensagem original e descartará a mensagem do commit de correção.

garoa
fonte
6
Você pode ler mais sobre rebasesquash / fixup nos documentos do Git .
Esta é uma ótima resposta. Sempre me perguntei por que recebo mensagens de confirmação de combinação.
jedd.ahyoung
66

Simplificando, ao rebasing uma série de commits, cada commit marcado como um squash, dá a você a oportunidade de usar sua mensagem como parte de uma mensagem pickou de rewordcommit.

Quando você usa fixupa mensagem daquele commit é descartada.

ocodo
fonte
Qual mensagem é mantida para fixupentão?
IgorGanapolsky
2
@IgorGanapolsky A mensagem do próximo commit na árvore git. Você basicamente "mescla" seu commit nele.
Alexandre Haroldo da Rocha
15

Do documento git-rebase, seção "modo interativo" :

Se você quiser dobrar dois ou mais commits em um, substitua o comando "pick" para o segundo commit e os subseqüentes por "squash" ou "fixup". Se os commits tiverem autores diferentes, o commit dobrado será atribuído ao autor do primeiro commit. A mensagem de commit sugerida para o commit dobrado é a concatenação das mensagens de commit do primeiro commit e daquelas com o comando "squash", mas omite as mensagens de commit de commits com o comando "fixup".

Paulo Lieuthier
fonte
13

Se a questão é qual é a diferença entre squashe fixupem git ao fazer git rebase --interactive , então a resposta é a mensagem de confirmação .

s, squash <commit> = usar confirmação, mas fundir com confirmação anterior

f, fixup <commit>= como "squash", mas descarta a mensagem de log deste commit


Por exemplo:

pick 22a4667 father commit message
squash 46d7c0d child commit message # case 1
# fixup 46d7c0d child commit message # case 2

A mensagem de confirmação após o rebase no caso 1 seria:

father commit message

child commit message

enquanto a mensagem de confirmação no caso 2 é:

father commit message
# no sub messages
Loi Nguyen Huynh
fonte
1

Eu mexi em extensões git e não consegui fazer com que muitos commits em um. Para fazer isso, tive que recorrer à linha de comando e achei este post útil

git rebase -i Head~2

Este é um rebase interativo e observe o seguinte:

  • ~ 2 aqui se refere a quantos commits você deseja envolver nesta operação, incluindo o cabeçalho atual
  • Você tem que editar a janela de edição interativa subsequente, deixar o primeiro item como "escolher" e substituir as linhas subsequentes por "squash". As instruções no link acima são muito mais claras se for opaco.
BraveNewMath
fonte
A postagem para a qual você tem um link é sobre a explicação mais clara que já vi sobre squash e conserto. Obrigado!
Simon Tewsi
0

Por que não perguntar ao próprio git? Quando você rebase com git-bash, ele diz:

pick 512b1d7 (some comment)
# Rebase 621b2e4..512b1d7 onto 621b2e4 (1 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
D:/code/fenixito-legacy-api/.git/rebase-merge/git-rebase-todo [unix] (11:57 23/10/2019)                                         1,1 start
"D:/code/xxx/.git/rebase-merge/git-rebase-todo" [UNIX] 27L, 1170C

Então você vê:

s, squash = usar commit, mas mesclar com commit anterior

f, fixup = como "squash", mas descarte a mensagem de log deste commit

WesternGun
fonte