Você pode executar git rebase --interactive
e reordenar D antes de B e esmagar D em A.
O Git abrirá um editor e você verá um arquivo como este, por exemplo: git rebase --interactive HEAD~4
pick aaaaaaa Commit A
pick bbbbbbb Commit B
pick ccccccc Commit C
pick ddddddd Commit D
# Rebase aaaaaaa..ddddddd onto 1234567 (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Agora você altera o arquivo com a seguinte aparência:
pick aaaaaaa Commit A
squash ddddddd Commit D
pick bbbbbbb Commit B
pick ccccccc Commit C
E o git agora mescla as mudanças de A e D em um commit e coloca B e C depois. Quando você não deseja manter a mensagem de confirmação de D, em vez de squash
, você usaria a fixup
palavra - chave. Para mais informações fixup
, consulte os git rebase
documentos ou confira esta pergunta, que tem boas respostas.
There is no tracking information for the current branch
erro ao fazer o novo rebase. Neste caso, você precisa especificar o número de commits que você quer trabalhar com, como este:git rebase -i HEAD~4
. Veja esta resposta .Nota: Você não deve alterar confirmações que foram enviadas para outro repositório de forma alguma, a menos que conheça as consequências .
git log --oneline -4
git rebase --interactive
Tipo
i
(Coloque o VIM no modo de inserção)Altere a lista para ficar assim (você não precisa remover ou incluir a mensagem de confirmação). Não cometa erros ortográficos
squash
! :Digite Escthen
ZZ
(Salvar e sair do VIM)Tipo
i
Altere o texto para o que você deseja que a nova mensagem de confirmação seja exibida. Eu recomendo que seja uma descrição das alterações no commit
A
eD
:Digite Escentão
ZZ
git log --oneline -4
git show E
Você criou um novo commit
E
. ConfirmaA
eD
não está mais em sua história, mas não se foi. Você ainda pode recuperá-los neste momento e por um tempogit rebase --hard D
(git rebase --hard
irá destruir as alterações locais! ).fonte
Para aqueles que usam o SourceTree :
Verifique se você ainda não enviou os commit.
Squash with previous
fonte
A rebase interativa funciona bem até que você tenha uma ramificação grande de recursos com 20 a 30 confirmações e / ou duas mesclagens do mestre ou da correção de conflitos enquanto você estava confirmando em sua ramificação. Mesmo encontrando meus commits através da história e substituindo
pick
porsquash
, não funcionou aqui. Então, eu estava procurando uma outra maneira e encontrei este artigo . Fiz minhas alterações para trabalhar isso em um ramo separado:Antes disso, recebi minha solicitação de recebimento com aproximadamente 30 confirmações com 2-3 mesclagens de conflitos principais e de correção. E depois disso, consegui um PR claro com um commit.
PS aqui é o script bash para executar essas etapas no automode.
fonte
mestre de checkout do $ git
$ git log --oneline
$ git rebase --onto HEAD ^^^ HEAD ^
$ git log --oneline
fonte
--oneline
? E parece que você caiuC
eB
, o que não é o que o OP pretendia.git show A
) e D, C e B foram perdidos no meu ref-log. Tinha quegit rebase D
voltar.