Atualmente estou trabalhando em um branch e quero que alguns commits se fundam em outros branches:
a-b-c-d-e-f-g (branchA)
/
--o-x-x-x-x-x-x-x-x-x-x (master)
\
x-x-x-x-x (branchB)
(As letras denotam confirmações e o "x" são confirmações irrelevantes.)
No entanto, percebi que seria uma boa ideia agrupar alguns commits. Eu quero "concatenar" o commit de a, d, e e g em um patch e enviá-lo ao master. Os commits b e f devem ir como um commit para o branchB. Existe uma boa maneira 'git'-ish de conseguir isso?
Respostas:
O comando que você está procurando é
git rebase
, especificamente a-i/--interactive
opção.Vou assumir que você deseja deixar o commit c no branch A, e que você realmente quer mover os outros commits para os outros branches, ao invés de fazer a fusão, uma vez que as fusões são diretas. Vamos começar manipulando o branch A.
Os
^
meios cometem o anterior, então este comando diz para rebase ramo Um usando o commit antes "a" como a base. O Git apresentará uma lista de commits neste intervalo. Reordene-os e diga ao git para esmagar os apropriados:Agora, a história deve ser semelhante a esta:
Agora, vamos pegar o commit recém-comprimido b + f para branchB.
E o mesmo para a + d + e + g para mestre:
Finalmente, atualize branchA para que aponte para c:
Devemos agora ter:
Observe que se você tiver vários commits que deseja mover entre branches, poderá usar o rebase novamente (não interativamente):
Finalmente, uma isenção de responsabilidade: é bem possível reordenar os commits de forma que alguns não se apliquem mais corretamente. Isso pode ser porque você escolheu uma ordem incorreta (colocar um patch antes do commit introduzindo o recurso que ele corrigiu); nesse caso, você deseja abortar o rebase (
git rebase --abort
). Caso contrário, você terá que consertar os conflitos de forma inteligente (assim como faz com os conflitos de mesclagem), adicionar as correções e, em seguida, corrergit rebase --continue
para seguir em frente. Essas instruções também são fornecidas pela mensagem de erro impressa quando ocorre o conflito.fonte
git branch -f branchA branchA^^
errado? A saber, o branch A não deveria estar apontando para c neste ponto, de modo que a primeira linha do diagrama estác (branchA)
e nãoc - [a+d+e+g] - [b+f] (branchA)
?git branch -f branchA branchA^^
por que você não pode simplesmente fazer umgit reset --hard <sha1 of c>
no ramo A?Onde
3
está o número de commits que precisam ser reordenados ( fonte ).Isso abrirá o vi , listando os commits do mais antigo (topo) ao mais recente (parte inferior).
Agora reordene as linhas, salve e saia do editor.
ddp
irá mover a linha atual para baixoddkP
irá mover a linha atual para cima ( fonte )fonte
git rebase --interactive
é o comando que você deseja.Exemplo:
O status atual é este:
Eu quero reordenar os commits
9a24b81
(Terceiro commit) e7bdfb68
(Segundo commit). Para fazer isso, primeiro encontro o commit antes do primeiro commit que queremos alterar . Este é o commit186d1e0
(primeiro commit).O comando a ser executado é
git rebase --interactive COMMIT-BEFORE-FIRST-COMMIT-WE-WANT-TO-CHANGE
, neste caso:Isso abre um arquivo no editor padrão com o seguinte conteúdo:
Observe que a ordem dos commits no arquivo é oposta àquela usada para o git log. No git log, o commit mais recente está no topo. Neste arquivo, o commit mais recente está na parte inferior.
Como o comentário na parte inferior do arquivo explica, há várias coisas que posso fazer, como suprimir, descartar e reordenar commits. Para reordenar os commits, edito o arquivo de forma que fique assim (os comentários da parte inferior não são exibidos):
O
pick
comando no início de cada linha significa "use (ou seja, inclua) este commit" e quando eu salvar o arquivo temporário com os comandos rebase e sair do editor, o git executará os comandos e atualizará o repositório e o diretório de trabalho:Observe o histórico de commits reescrito.
Links:
fonte
git rebase --interactive
para atingir a meta do OP?Se quiser reordenar apenas os dois últimos commits , você pode
git reorder
usar este alias: https://stackoverflow.com/a/33388211/338581fonte
git rebase é o que você deseja. Verifique a opção --interactive.
fonte