Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.43.0 11/20/23
- 2.42.1 11/02/23
- 2.42.0 no changes
- 2.41.0 06/01/23
- 2.40.1 no changes
- 2.40.0 03/12/23
- 2.39.3 04/17/23
- 2.39.1 → 2.39.2 no changes
- 2.39.0 12/12/22
- 2.38.1 → 2.38.5 no changes
- 2.38.0 10/02/22
- 2.37.3 → 2.37.7 no changes
- 2.37.2 08/11/22
- 2.36.3 → 2.37.1 no changes
- 2.36.2 06/23/22
- 2.35.1 → 2.36.1 no changes
- 2.35.0 01/24/22
- 2.34.1 → 2.34.8 no changes
- 2.34.0 11/15/21
- 2.33.2 → 2.33.8 no changes
- 2.33.1 10/12/21
- 2.32.1 → 2.33.0 no changes
- 2.32.0 06/06/21
- 2.31.1 → 2.31.8 no changes
- 2.31.0 03/15/21
- 2.30.1 → 2.30.9 no changes
- 2.30.0 12/27/20
- 2.29.1 → 2.29.3 no changes
- 2.29.0 10/19/20
- 2.28.1 no changes
- 2.28.0 07/27/20
- 2.27.1 no changes
- 2.27.0 06/01/20
- 2.26.1 → 2.26.3 no changes
- 2.26.0 03/22/20
RESUMO
git rebase [-i | --interactive] [<opções>] [--exec <cmd>] [--onto <nova-base> | --keep-base] [<upstream> [<ramo>]] git rebase [-i | --interactive] [<opções>] [--exec <cmd>] [--onto <nova-base>] --root [<ramo>] git rebase (--continue | --skip | --abort | --quit | --edit-todo | --show-current-patch)
DESCRIÇÃO
Caso o <ramo> seja utilizado, o comando git rebase executará um git
switch <ramo>
automaticamente antes de fazer qualquer outra coisa. Caso
contrário, ele permanecerá no ramo atual.
Caso o <upstream>
não seja definido, as opções "upstream" configuradas em
branch.<nome>.remote
e no branch.<nome>.merge
serão utilizadas (para
mais detalhes consulte git-config[1]), assim como será assumida a
opção --fork-point
. Caso você não esteja atualmente em nenhuma
ramificação ou se a ramificação atual não tiver um "upstream" configurado, o
"rebase" será cancelado.
Todas as alterações feitas através de commits no ramo atual, mas que não
estão na <upstream>, são salvas em uma área temporária. Este é o mesmo
conjunto dos commits que seriam exibidos por git log <upstream>..HEAD
; ou
pelo comando git log 'fork_point'..HEAD
, caso --fork-point
esteja ativo
(veja a descrição em --fork-point
abaixo); ou através do git log HEAD
,
caso a opção --root
for seja utilizada.
A ramificação atual é redefinida para <upstream> ou <newbase> caso a opção
--onto
seja utilizada. Isso tem exatamente o mesmo efeito que git reset
--hard <upstream>
(ou <newbase>). O ORIG_HEAD
está definido para apontar
no cume do ramo antes da redefinição.
Os commits que foram salvos anteriormente na área temporária são reaplicadas
no ramo atual, uma por uma e em ordem. Observe que quaisquer commits no
HEAD
que introduzam as mesmas alterações textuais que um commit no
HEAD
.. <upstream>
são omitidas (ou seja, um patch já aceito na inicial
com uma mensagem de commit ou carimbo de data e hora diferente, serão
ignorados).
É possível que uma falha da mesclagem impeça que este processo seja
completamente automático. Você terá que resolver qualquer falha da
mesclagem e executar o comando git rebase --continue
. Outra opção é
ignorar o commit que causou a falha da mesclagem com o comando git rebase
--skip
. Para verificar o <ramo> original e remover os arquivos de trabalho
.git/rebase-apply, utilize o comando git rebase --abort
.
Suponha que o seguinte histórico exista e que o ramo atual seja "topic":
A---B---C topic / D---E---F---G master
A partir deste ponto, o resultado de um dos seguintes comandos:
git rebase master git rebase master topic
seria:
A'--B'--C' topic / D---E---F---G master
OBSERVAÇÃO: Este último formulário é apenas uma abreviação de git checkout topic
seguido por git rebase master
. Quando a reconstrução (rebase) sair do topic
será
mantido o ramo que foi averiguado.
Caso a ramificação upstream já contiver uma alteração que você fez (porque
você enviou um patch que foi aplicado na upstream por exemplo), então este
commit será ignorado. Por exemplo, executando o comando git rebase master
no histórico a seguir (onde A'
e A
introduzem o mesmo conjunto de
alterações, mas possuem informações diferentes de quem fez o commit):
A---B---C topic / D---E---A'---F master
vai resultar em:
B'---C' topic / D---E---A'---F master
Aqui está como você transplantaria um ramo do tópico com base em um ramo
para outro, para fingir que você bifurcou o ramo do tópico deste último
ramo, utilizando rebase --onto
.
Primeiro, vamos supor que o seu tópico seja baseado no ramo next. Por exemplo, um recurso desenvolvido em topic depende de algumas funcionalidades encontradas em next.
o---o---o---o---o master \ o---o---o---o---o next \ o---o---o topic
Queremos criar um tópico bifurcado no ramo master; porque a funcionalidade da qual o tópico depende foi mesclado na ramificação master mais estável. Queremos que a nossa árvore fique assim:
o---o---o---o---o master | \ | o'--o'--o' topic \ o---o---o---o---o next
Podemos conseguir isso utilizando o seguinte comando:
git rebase --onto master next topic
Um outro exemplo da opção --onto
é reconstruir a fundação da parte de uma
ramificação. Se tivermos a seguinte situação:
H---I---J topicB / E---F---G topicA / A---B---C---D master
então o comando
git rebase --onto master topicA topicB
resultaria em:
H'--I'--J' topicB / | E---F---G topicA |/ A---B---C---D master
É útil quando o topicB não depender do topicA.
Um intervalo dos commits também pode ser removido com a reconstrução rebase. Se tivermos a seguinte situação:
E---F---G---H---I---J topicA
então o comando
git rebase --onto topicA~5 topicA~3 topicA
resultaria na remoção dos commits F e G:
E---H'---I'---J' topicA
É útil caso F e G estejam de alguma forma com defeitos ou não deveriam fazer parte do topicA. Observe que o argumento para --onto e o parâmetro <upstream> podem ser qualquer commit-ish válido.
Em caso de conflito, o git rebase irá parar no primeiro commit problemático e deixar os marcadores de conflito na árvore. Você pode utilizar o git diff para localizar os marcadores (<<<<<<) e fazer edições para resolver o conflito. Para cada arquivo que você edita, é necessário informar ao Git que o conflito foi resolvido, normalmente isso seria feito com
git add <nome-do-arquivo>
Depois de resolver o conflito manualmente e atualizar o índice com a resolução desejada, você pode continuar o processo de reconstrução com o comando
git rebase --continue
Como alternativa, você pode desfazer o git rebase com
git rebase --abort
OPÇÕES
- --onto <nova-base>
-
Ponto de partida onde criar os novos commits. Caso a opção --onto não seja utilizada, o ponto inicial é <upstream>. Pode ser qualquer commit válido e não apenas um nome de um ramo já existente.
Como um caso especial, você pode utilizar "A...B" como um atalho para a base de mesclagem A e B caso haja exatamente uma base para mesclagem. Você pode deixar de fora no máximo um de A e B; nesse caso, a predefinição retorna para
HEAD
. - --keep-base
-
Defina o ponto de partida para criar os novos commits para a mesclagem base do <upstream> <ramo>. Executando o comando git rebase --keep-base <upstream> <ramo> é o mesmo que executar o comando git rebase --onto <upstream>… <upstream>.
Esta opção é útil no caso onde se está desenvolvendo um recurso em cima de um ramo upstream. Enquanto o recurso está sendo trabalhado, o ramo upstream pode avançar e talvez não seja a melhor ideia continuar reconstruindo no topo do upstream, porém manter a base do commit como está.
Embora esta opção e o
--fork-point
encontrem a base da mesclagem entre <upstream> e <ramo>, esta opção utiliza a base da mesclagem como o ponto inicial onde os novos commits serão criados, enquanto--fork-point
utiliza a mesclagem da base para determinar o conjunto dos commits que serão reconstruídos.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- <upstream>
-
Ramo upstream para fazer a comparação. Pode ser qualquer commit válido, não apenas um nome de uma ramo já existente. A predefinição retorna para "upstream" configurada para o ramo atual.
- <ramo>
-
Ramo de trabalho; A predefinição retorna para
HEAD
. - --continue
-
Reinicie o processo de reformulação após resolver um conflito de mesclagem.
- --abort
-
Interrompa a operação de reconstrução da fundação e redefina o
HEAD
para o ramo original. Caso <ramo> seja informado quando a operação de reconstrução da fundação seja iniciada, oHEAD
será redefinido para <ramo>. Caso contrário, o HEAD será redefinido para onde estava quando a operação de reconstrução foi iniciada. - --quit
-
Interrompa a operação de reconstrução, porém o
HEAD
não será redefinido para o ramo original. Como resultado, o índice e a árvore de trabalho também permanecem inalterados. Caso uma entrada temporária stash seja criada utilizando--autostash
, ela será salva na lista stash. - --apply
-
Utilize estratégias para aplicar o "rebase" (invocando
git-am
internamente). Esta opção poderá se tornar não operacional no futuro uma vez que o processo interno da mesclagem processe tudo o que a opção --apply fizer.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --empty={drop,keep,ask}
-
Como lidar com commits que não estão vazias para iniciar e não são escolhas seletivas limpas de nenhum commit upstream, mas que ficam vazias após a reconstrução (porque elas já contêm um subconjunto de alterações na upstream). Com drop (a predefinição), os commits que ficam vazias são descartadas. Com keep, estes commits são mantidos. Com o comando ask (implícito através da opção
--interactive
), uma reconstrução rebase será interrompida quando um commit vazia for aplicado, permitindo que você escolha se elimina, edita mais arquivos ou apenas faça o commit das alterações vazias. Outras opções, como--exec
, utilizarão a predefinição drop, a menos que a opção-i/--interactive
seja informado de forma explicita.Observe que, os commits que começam vazios são mantidos (a menos que a opção
--no-keep-empty
seja utilizado) e os commits que são escolhas limpas (conforme determinado pelo comandogit log --cherry-mark ...
) são detectados e descartados como uma etapa preliminar (a menos que a opção `--reapply-cherry-picks seja utilizado).Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --no-keep-empty
- --keep-empty
-
Não mantenha os commits que começam vazios antes da reconstrução (ou seja, que não alteram em nada a origem) no resultado. A predefinição é manter os commits que começam vazios, pois a criação destes commits requer o encaminhamento da opção
--allow-empty override
para o comandogit commit
, significa que um usuário está criando intencionalmente tal commit e portanto, deseja mantê-lo.A utilização desta opção é bem rara, já que você pode se livrar dos commits que iniciam vazios simplesmente executando uma reconstrução interativa e removendo as linhas correspondentes ao commit que você não quer. Está opção existe como um atalho por mera conveniência, para casos onde as ferramentas externas gerem muitos commits vazios e você que todos eles sejam removidos.
Para os commits que não começam vazios, mas ficam vazios após a reconstrução (rebase), consulte a opção
--empty
.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --reapply-cherry-picks
- --no-reapply-cherry-picks
-
Reaplique todas as escolhas seletivas que estejam limpas de qualquer commit "upstream" em vez inviabilizá-los por completo. (Então, caso estes commits se tornem vazios depois da reconstrução, por conter um subconjunto de alterações da "upstream", o comportamento em direção à eles é controlado através da opção
--empty
.)É predefinido que (ou se `--no-reapply-cherry-picks 'for fornecido), estes commits serão automaticamente eliminados. Como isso requer a leitura de todos os commits upstream, isso pode custar caro nos repositórios com uma grande quantidade de commits na upstream que precisam ser lidos.
A opção
--reapply-cherry-picks
permite que a reconstrução anteceda a leitura de todos os commits "upstream", melhorando muito o desempenho.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --allow-empty-message
-
No-op. A reconstrução dos commits com uma mensagem vazia costumava falhar, esta opção substitui este comportamento, permitindo que os commits com mensagens vazias sejam refeitas. Agora os commits com uma mensagem vazia não causam mais a interrupção do "rebasing".
Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --skip
-
Reinicie o processo de reconstrução da fundação ignorando o patch atual.
- --edit-todo
-
Edite a lista de tarefas durante uma nova reconstrução interativa.
- --show-current-patch
-
Exiba o patch atual em uma nova recuperação interativa ou quando a nova recuperação for interrompida por causa de conflitos. É o equivalente ao
git show REBASE_HEAD
. - -m
- --merge
-
Utilize estratégias de mesclagem para fazer o
rebase
. Quando a estratégia de mesclagem recursiva (predefinida) for utilizada, permite que orebase
esteja ciente das renomeações no lado upstream. Esta é a predefinição.Observe que uma mesclagem de reconstrução (rebase) funciona repetindo cada commit da ramificação de trabalho na parte do topo <upstream>. Por esse motivo, quando ocorre um conflito na mesclagem, o lado relatado como nosso é a série até agora reformulada, começando com <upstream> e deles é o ramo de trabalho. Em outras palavras, os lados são trocados.
Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- -s <estratégia>
- --strategy=<estratégia>
-
Use a estratégia de mesclagem informada. Caso não haja a opção `-s , o git merge-recursive será utilizado em seu lugar. implica no uso da opção --merge.
Como o git rebase repete cada commit do ramo de trabalho no cume do ramo <upstream> utilizando a estratégia informada, o uso da estratégia our simplesmente esvazia todos os patches do <ramo>, que faz pouco sentido.
Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- -X <opção-da-estratégia>
- --strategy-option=<opção-da-estratégia>
-
Encaminhe a <opção-de-estratégia> para a estratégia da mesclagem. implica no uso da opção
--merge
e, se nenhuma estratégia foi definida,-s recursive
. Observe a reversão do ours (nossos) e theirs (deles), conforme observado acima para a opção-m
.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --rerere-autoupdate
- --no-rerere-autoupdate
-
Permita que o mecanismo "rerere" atualize o índice com o resultado da resolução automática de conflitos, caso seja possível.
- -S[<keyid>]
- --gpg-sign[=<keyid>]
- --no-gpg-sign
-
Commits assinados com o GPG O argumento
keyid
é opcional e a predefinição retorna para a identidade de quem fez o commit; caso seja utilizado, deve estar anexado a opção e sem espaço. A opção--no-gpg-sign
é útil para revogar a variável de configuraçãocommit.gpgSign
e a anterior--gpg-sign
. - -q
- --quiet
-
Fique em silêncio Implies --no-stat.
- -v
- --verbose
-
Seja loquaz. Implica no uso de
--stat
. - --stat
-
Exiba uma descrição do que mudou na upstream desde a última reconstrução (rebase). O diffstat também é controlado pela opção de configuração
rebase.stat
. - -n
- --no-stat
-
Não mostre um "diffstat" como parte do processo de reconstrução da fundação (rebase).
- --no-verify
-
Este comando ignora o gancho "pre-rebase". Consulte também githooks[5].
- --verify
-
É predefinido que seja permitido que o gancho "pre-rebase" seja executado. Esta opção pode ser usada para substituir o comando ` --no-verify`. Consulte também githooks[5].
- -C<n>
-
Assegure que pelo menos
<n>
linhas ao redor do contexto coincidente antes e depois de cada alteração. Quando há menos linhas de contexto ao redor, todas elas devem coincidir. É predefinido que nenhum contexto seja ignorado. Implica no uso da opção --apply.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --no-ff
- --force-rebase
- -f
-
Reproduza individualmente todos os commits reconstruídos em vez de avançar rapidamente sobre os que estejam inalterados. Isso garante que todo o histórico do ramo reconstruído seja composto por novos commits.
Pode ser útil depois de reverter uma mesclagem do ramo "topic", pois esta opção recria o ramo "topic" com os novos commits, para que possa ser recuperado com êxito sem precisar "reverter a reversão" (para mais detalhes, consulte o link: howto/revert-a-fafe-merge.html [Como reverter uma falha da mesclagem]).
- --fork-point
- --no-fork-point
-
Utilize reflog para encontrar um ancestral comum melhor entre a <upstream> e o <ramo> ao calcular quais os commits foram introduzidos pelo <ramo>.
Quando "--fork-point" está ativo o fork_point será utilizado em vez do
<upstream>
calcular o conjunto dos commits para fazer o "rebase" onde fork_point é o resultado do comandogit merge-base --fork-point <upstream> <ramo>
(consulte git-merge-base[1]). Caso o fork_point termine vazio, o<upstream>
será utilizado como substituto.Caso a <upstream> seja utilizada na linha de comando, a predefinição será
--no-fork-point
, caso contrário, a predefinição será--fork-point
.Caso o seu ramo teve como base no <upstream>, porém <upstream> foi retrocedido e o seu ramo contém commits que foram eliminados, esta opção pode ser utilizada com a opção
--keep-base
para eliminar estes commits do seu ramo.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --ignore-whitespace
- --whitespace=<opção>
-
Estas opções são repassados para o comando git apply que aplica o patch (consulte git-apply[1]). Implica no uso da opção --apply.
Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --committer-date-is-author-date
- --ignore-date
-
Estas opções são passados para o comando git am para alterar facilmente as datas dos commits onde o "rebase" foi feito (consulte git-am[1]).
Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --signoff
-
Adicione uma resposta Assinado-por: a todos os commits que tiveram a sua fundação reconstruída. Observe que caso a opção
--interactive
seja utilizada, apenas os commit marcados para serem selecionados, editados ou reformulados terão um caracteres de resposta adicionado.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- -i
- --interactive
-
Faça uma lista dos commits que estão prestes a serem reconstruídos. Deixe que o usuário edite esta lista antes da reconstrução. Este modo também pode ser utilizado para dividir os commits (consulte DIVIDINDO OS COMMITS abaixo).
O formato da lista dos commits pode ser alterado definindo a opção de configuração
rebase.instructionFormat
. Um formato de instrução personalizado terá automaticamente o hash longo do commit anexado ao formato.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- -r
- --rebase-merges[=(rebase-cousins|no-rebase-cousins)]
-
É predefinido que uma reconstrução simplesmente remova os commits mesclados da lista de tarefas e as coloca em uma única ramificação linear. Com a opção
--rebase-merges
, a reconstrução tentará preservar a estrutura da ramificação dentro dos commits que serão reexaminadas, recriando a mesclagem dos commits. Quaisquer conflitos na mesclagem que forem resolvidos ou nas alterações manuais destes commits mesclados terão que ser resolvidos/reaplicados manualmente.É predefinido que ou quando
no-rebase-cousins
seja utilizado, os commits que não possuam<upstream>
como ancestral direto, manterão o seu ponto do ramo original, ou seja, os commits que seriam excluídos pela opção git-log[1]--ancestry-path
, por predefinição manterá a sua ancestralidade original. Caso o modorebase-cousins
esteja ativo, estes commits serão reconstruídos para a<upstream>
(ou<onto>
, caso seja utilizado).O modo
--rebase-merges
é semelhante (em espírito) a opção descontinuada--preserve-merges
porém trabalha com reconstrução interativa (rebases), onde os commits possam ser reordenados, inseridos ou eliminados a vontade.Atualmente, só é possível recriar a mesclagem dos commits utilizando a estratégia de mesclagem
recursive
(recursiva); Diferentes estratégias de mesclagem podem ser utilizada apenas através dos comandos explícitos comoexec git merge -s <strategy> [...]
.Consulte também RECONSTRUINDO AS MESCLAGENS e OPÇÕES INCOMPATÍVEIS abaixo.
- -p
- --preserve-merges
-
[DESCONTINUADO: utilize
--rebase-merges
] Recrie os commits mesclados em vez de achatar o histórico, reproduzindo os commits introduzidos por uma mesclagem do commit. As resoluções dos conflitos da mesclagem ou das emendas manuais para mesclar os commits não são preservadas.Utiliza o mecanismo
--interactive
internamente, porém ao combiná-lo com a opção--interactive
de forma explícita, em geral não é uma boa ideia a menos que saiba o que está fazendo (consulte BUGS abaixo).Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- -x <cmd>
- --exec <cmd>
-
Anexe "exec <cmd>" após cada linha, criando um commit no final do histórico. O
<cmd>
será interpretado como um ou mais comandos do shell. Qualquer comando que falhar interromperá a reconstrução da fundação, com o código de encerramento igual a 1.É possível executar vários comandos utilizando uma instância da opção
--exec
com vários comandos:git rebase -i --exec "cmd1 && cmd2 && ..."
ou utilizando mais de um
--exec
:git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
Caso a opção
--autosquash
seja utilizado, as linhas "exec" não serão anexadas aos commits intermediários e aparecerão apenas no final de cada série de compressão/correção.Utiliza o mecanismo
--interactive
internamente, porém pode ser executado sem a opção--interactive
de forma explicita.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --root
-
Reconstrói todos os commits acessíveis a partir do <ramo>, em vez de limitá-los com a <upstream>. Permite a reestruturação dos commit da raiz em um ramo. Quando utilizado com a opção
--onto
, será ignorado as alterações já contidas em <newbase> (em vez de <upstream>) enquanto que sem a opção--onto
a operação ocorrerá em todas as alterações. Quando utilizado junto com ambas as opções--onto
e--preserve-merges
, todos os commits das raízes serão reescritos para ter o <newbase> como a sua origem.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --autosquash
- --no-autosquash
-
Quando a mensagem do registro log do commit começar com "squash! …" (ou "fixup! …"),e já existe um commit na lista de tarefas que coincidem com o mesmo
...
, altera a lista de tarefas automaticamente do rebase -i para que o commit marcado para ser comprimido venha logo após o commit que será modificado e altere a ação do commit movido depick
parasquash
(oufixup
). Um commit coincide com...
caso haja a coincidência do assunto do commit ou se o...
se referir ao hash do commit. Como alternativa, as coincidências que forem parciais ao assunto do commit, também funcionam. A maneira recomendada para se criar os commits para correção/compressão é utilizando as opções--fixup
/--squash
do comando git-commit[1].Caso a opção
--autosquash
esteja predefinitivamente ativada utilizando a variável de configuraçãorebase.autoSquash
, esta opção poderá ser utilizada para substituir e desativar esta configuração.Consulte também a seção "OPÇÕES INCOMPATÍVEIS" logo abaixo.
- --autostash
- --no-autostash
-
Crie automaticamente uma entrada temporária stash antes do início da operação e aplique-a ao finalizar. Isso significa que é possível executar a reconstrução (rebase) em uma árvore de trabalho suja. No entanto, use com cuidado: a aplicação stash final após uma nova reconstrução bem-sucedida pode acabar em conflitos não triviais.
- --reschedule-failed-exec
- --no-reschedule-failed-exec
-
Reagende automaticamente os comandos
exec
que falharam. Isso só faz sentido no modo interativo (ou quando uma opção--exec
for utilizada).
OPÇÕES INCOMPATÍVEIS
As seguintes opções:
-
--apply
-
--committer-date-is-author-date
-
--ignore-date
-
--ignore-whitespace
-
--whitespace
-
-C
são incompatíveis com as seguintes opções:
-
--merge
-
--strategy
-
--strategy-option
-
--allow-empty-message
-
--[no-]autosquash
-
--rebase-merges
-
--preserve-merges
-
--interactive
-
--exec
-
--no-keep-empty
-
--empty=
-
--reapply-cherry-picks
-
--edit-todo
-
--root quando utilizado em conjunto com --onto
Além disso, os seguintes pares de opções são incompatíveis:
-
--preserve-merges e --interactive
-
--preserve-merges e --signoff
-
--preserve-merges e --rebase-merges
-
--preserve-merges e --empty=
-
--keep-base e --onto
-
--keep-base e --root
-
--fork-point e --root
DIFERENÇAS COMPORTAMENTAIS
O git rebase possui duas estruturas primárias: `apply` e `merge`. (A aplicação da estrutura era conhecido como 'am', porém o nome causava confusão já que parecia um verbo em vez de um substantivo. Além disso, a estrutura `merge` era informada como 'interactive backend', porém agora também é usado para casos não interativos. Ambos foram renomeados com base na funcionalidade de baixo nível que sustentava cada um.) Há algumas diferenças sutis em como estes dois processos internos se comportam: Commits vazios ~~~~~~~~~~~~~ A estrutura aplicada infelizmente descarta os commits vazios de forma intencional, ou seja. Os commits que começaram vazios, contudo na prática, é algo raro. Também descarta os commits que se tornam vazios e não há uma opção para controlar este comportamento. É predefinido que a estrutura da mesclagem mantenha os commits intencionalmente vazios (com `-i` são marcados como vazio no editor da lista de tarefas, ou podem ser descartados automaticamente com a opção `--no-keep-empty`). Semelhante à estrutura aplicada, é predefinido que a estrutura da mesclagem derrube os commits que se tornaram vazios, a menos que as opções `-i` ou `--interactive` sejam definidas (nesse caso, ele para e pergunta ao usuário o que fazer). A estrutura da mesclagem também possui uma opção --empty={drop,keep,ask} para alterar o comportamento da manipulação dos commits que ficam vazios. Detecção da renomeação do diretório ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Devido à falta de informações precisas sobre as árvores (que surge de construções dos ancestrais falsos com informações limitadas disponíveis nos patches), a detecção da renomeação do diretório é desativado na estrutura da aplicação. A desativação da detecção da renomeação do diretório, significa que se um lado do histórico renomear um diretório e o outro adicionar novos arquivos no diretório antigo, então os novos arquivos serão deixados para trás no diretório antigo sem qualquer aviso, durante a reconstrução onde você possa talvez querer mover estes arquivos, para o novo diretório. A detecção da renomeação do diretório funciona com a estrutura da mesclagem, neste caso, fornecendo informações para você. Contexto ~~~~~~~~ A aplicação da estrutura funciona ao criar uma sequencia de patches (chamando o `format-patch` internalmente), então se aplicam os patches em sequência (invocando o `am` internamente). Os patches são compostos de vários pedaços, cada um com linhas numeradas, o contexto da região, e as alterações atuais. As linhas numeradas devem ser tomadas com alguma imprecisão, já que antes o outro lado provavelmente terá inserido ou terá excluído as linhas no arquivo. O contexto da região destina-se no auxílio para encontrar como ajustar as linhas numeradas na ordem para aplicar as alterações nas linhas corretas. No entanto, caso ao redor das várias áreas do código tenham as mesmas linhas de contexto, um código errado pode ser selecionado. Existem casos no mundo real onde isso fez com que os commits fossem reaplicados de forma incorreta e nenhum conflito foi relatado. Definindo o `diff.context` para um valor maior, isso pode impedir que estes tipos de problemas ocorram, porém aumenta a chance de conflitos espúrios (uma vez que exigirá mais linhas que coincidam com o contexto para serem aplicados). A estrutura da mesclagem trabalha com a cópia completa de casa arquivo relevante, isolando-os destes tipos de problemas. Rotulagem dos marcadores de conflitos ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quando há conteúdos conflitantes, o mecanismo da mesclagem tenta anotar os marcadores de conflito de cada lado com os commits de onde o conteúdo veio. Como a estrutura descarta o original, as informações sobre os commits reconstruídos e seus pais (em vez disso, gera novos commits falsos com base nas informações limitadas no patches que foram gerados), estes commits não podem ser identificados; em vez disso tem que retornar para um resumo do commit. Além disso, quando `merge.conflictStyle` é definido para 'diff3', a estrutura aplicada utilizará uma "mesclagem reconstruída da base" para rotular o conteúdo da base mesclada e portanto, não fornecer qualquer informações sobre o commit da base mesclada. A estrutura da mesclagem funciona com commits completos nos dois lados da história e portanto, não tem tais limitações. Ganchos ~~~~~~~ A estrutura da aplicação não chama tradicionalmente o gancho pós-commit, enquanto a estrutura da mesclagem chama. Ambos chamaram o gancho pós-averiguação, embora a estrutura da mesclagem reduza a sua saída. Além disso, ambas as estruturas chamam apenas o gancho pós-averiguação com o ponto de partida para fazer o commit da reconstrução da fundação (rebase), nem o commit intermediário, nem o commit final. Em cada caso, o chamado desses ganchos foi por acidente de implementação em vez de design (os dois processos internos eram originalmente implementados como scripts shell e passaram a chamar outros comandos como o 'git checkout' ou o 'git commit' que seriam chamados de ganchos). Ambos os processos internos devem ter o mesmo comportamento, embora não seja inteiramente claro qual (caso existam), está correto. Provavelmente faremos a reconstrução (rebase) parar chamando um destes ganchos no futuro. Interrupção ~~~~~~~~~~~ A aplicação da estrutura possui problemas de segurança relacionada com interrupção de tempo; caso o usuário pressione Ctrl+C no momento errado ao tentar interromper o processo 'rebase' (reconstrução), o processo então pode entrar em uma condição ele não pode ser parado posteriormente com um comando `git rebase --abort`. A estrutura da mesclagem não parece sofrer da mesma deficiência. (Consulte https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ para obter mais detalhes.) Reformulando o Commit ~~~~~~~~~~~~~~~~~~~~~ Quando ocorre um conflito durante o processo 'rebase', o processo para e pergunta ao usuário para resolver o problema. Como o usuário pode precisar fazer muitas alterações enquanto resolve os conflitos, depois que os conflitos forem resolvidos e o usuário tenha executado o comando `git rebase --continue`, o 'rebase' deverá abrir o editor e perguntar ao usuário para atualizar a mensagem do commit. A estrutura da mesclagem faz isso, enquanto a estrutura aplica cegamente a mensagem do commit original. Diferenças diversas ~~~~~~~~~~~~~~~~~~~ Existem mais algumas diferenças comportamentais que a maioria das pessoas considerariam fazer de forma inconsequente, porém são mencionadas por questões de integridade: * Reflog: As duas estruturas que utilizarão palavras diferentes durante a descrição das alterações feitas no reflog, embora ambos façam a utilização da palavra "rebase" * Mensagens de progresso, informacionais e de erro: As duas estruturas fornecem um progresso ligeiramente diferente das mensagens informantes. Além disso, a estrutura aplicada grava uma mensagens de erro (como "Os seus arquivos serão substituídos...") para o stdout, enquanto a mesclagem da estrutura escrevem eles no stderr. * Diretórios de estado: As duas estruturas mantêm a sua condição em diferentes diretórios dentro do `.git/` ESTRATÉGIAS DE MESCLAGEM ------------------------ O mecanismo da mesclagem (comandos `git merge` e `git pull`) permite que as estruturas das 'estratégias de mesclagem' sejam escolhidas com a opção `-s`. Algumas estratégias também podem ter suas próprias opções, que podem ser passadas usando `-X<opção>` como argumentos para o comando `git merge` e/ou `git pull`. resolve:: Isso só pode resultar em dois cabeçalhos (ou seja, a ramificação atual e uma outra ramificada da que você obteve) utilizando um algoritmo de mesclagem de três vias. Ele tenta detectar cuidadosamente as ambiguidades cruzadas da mesclagem e geralmente é considerado seguro e rápido. recursive:: Isso pode resolver apenas duas cabeças usando o algoritmo da mesclagem de 3 vias. Quando há mais de um ancestral comum que pode ser usado para a mesclagem de 3 vias, ele cria uma árvore mesclada dos ancestrais comuns e o usa como a árvore de referência para a mesclagem de 3 vias. Foi informado que isso resulta em menos conflitos durante mesclagem sem causar distorções pelos testes feitos nas mesclagens reais dos commits, retiradas do histórico de desenvolvimento do Linux kernel 2.6. Além disso, isso pode detectar e manipular as mesclagens envolvendo renomeações, porém atualmente não pode fazer uso das cópias detectadas. Essa é a estratégia de mesclagem predefinida ao extrair ou mesclar um ramo. + A estratégia 'recursiva' pode ter as seguintes opções: ours;; Esta opção impõem que os pedaços conflitantes que sejam resolvidos de forma automática e de maneira limpa, favorecendo a 'nossa' versão. As alterações vindos de outra árvore que não conflitam com o nosso lado são refletidas no resultado da mesclagem. Para um arquivo binário, todo o conteúdo é retirado do nosso lado. + Isso não deve ser confundido com a estratégia da 'nossa' de mesclagem, que sequer olha para o que a outra árvore contém. Descarta tudo o que a outra árvore fez, declarando que o 'nosso' histórico contém tudo o que aconteceu nela. theirs;; Este é o oposto do 'nosso'; observe que, diferentemente do 'nosso', não existe uma estratégia de mesclagem 'deles' para confundir esta opção de mesclagem. patience;; Com esta opção, 'merge-recursive' gasta um pouco de tempo extra para evitar as distorções que às vezes ocorrem devido as coincidência das linhas sem importância (como, por exemplo, chaves das funções distintas). Use isso quando os ramos que serão mesclados divergirem bastante. Consulte também git-diff[1] `--patience`. diff-algorithm=[patience|minimal|histogram|myers];; Informa ao 'merge-recursive' para usar um algoritmo diff diferente, que pode ajudar a evitar as distorções que ocorrem devido as linhas coincidentes sem importância (como chaves das funções distintas). Consulte também git-diff[1] `--diff-algorithm`. ignore-space-change;; ignore-all-space;; ignore-space-at-eol;; ignore-cr-at-eol;; Trata as linhas com o tipo indicado da mudança do espaço como inalterado por uma mesclagem de três vias. As alterações de espaço combinadas com outras alterações em uma linha não são ignoradas. Consulte também git-diff[1] `-b`, `-w`, `--ignore-space-at-eol`, e `--ignore-cr-at-eol`. + * Caso a versão 'their' (dele) introduzir apenas as alterações de espaço em uma linha, a 'our' (nossa) versão será utilizada; * Caso a 'our' (nossa) versão introduzir alterações nos espaços, porém a versão 'their' (dele) incluir uma alteração substancial, a versão 'their' (dele) será utilizada; * Caso contrário, a mesclagem continuará de forma usual. renormalize;; Executa uma averiguação e um check-in virtual de três estágios em um arquivo ao resolver uma mesclagem de três vias. Esta opção deve ser utilizada ao mesclar os ramos com diferentes filtros que estejam limpos ou as regras normais para a quebra de linha. Para obter mais detalhes, consulte "Mesclando ramificações com diferentes atributos de check-in/check-out" em gitattributes[5]. no-renormalize;; Desativa a opção `renormalize`. Substitui a variável de configuração `merge.renormalize`. no-renames;; Desativa a detecção de renomeação. Isso substitui a variável de configuração `merge.renames`. Consulte tambémgit-diff[1] `--no-renames`. find-renames[=<n>];; Liga a detecção de renomeação, configurando opcionalmente o limite de similaridade. Esta é a predefinição. Isso substitui a configuração da variável 'merge.renames'. Consulte também git-diff[1] `--find-renames`. rename-threshold=<n>;; É um sinônimo obsoleto para `find-renames=<n>`. subtree[=<caminho>];; Essa opção é uma forma mais avançada da estratégia da 'subárvore', onde a estratégia adivinha como as duas árvores devem ser deslocadas para coincidirem uma com a outra durante a mesclagem. Em vez disso, o caminho definido é prefixado (ou removido desde o início) para criar a forma das duas árvores que serão coincididas. octopus:: Isso resolve os casos com mais de dois cabeçalhos, porém se recusa a fazer uma mesclagem complexa que precise de uma resolução manual. Destina-se primeiramente para ser usado para agrupar junto o tópico dos cabeçalhos. Esra é a estratégia de mesclagem predefinida durante a extração ou a mesclagem com mais de um ramo. ours:: Isso resolve qualquer quantidade dos cabeçalhos, porém a árvore resultante da mesclagem é sempre a do cabeçalho atual do ramo, ignorando efetivamente todas as alterações de todas os outros ramos. Ele deve ser usado para substituir o histórico antigo de desenvolvimento das ramificações laterais. Observe que isso é diferente da opção `-Xours` da estratégia de mesclagem 'recursiva'. subtree:: Esta é uma estratégia recursiva modificada. Ao mesclar as árvores 'A' e 'B', caso 'B' corresponda a uma subárvore de 'A', o 'B' será ajustado primeiro para coincidir à estrutura da árvore 'A', em vez de ler as árvores no mesmo nível. Esse ajuste também é feito na árvore ancestral comum. Com as estratégias que usma a mesclagem de 3 vias (incluindo a predefinição, 'recursive'), caso uma alteração seja feita em ambas as ramificações, porém depois revertida em uma das ramificações, essa alteração estará presente no resultado mesclado; algumas pessoas acham este comportamento confuso. Isso ocorre porque apenas os cabeçalhos e a base da mesclagem são consideradas ao fazer uma mesclagem, e não os commits individuais. Portanto, o algoritmo da mesclagem considera a alteração revertida como nenhuma alteração e substitui a versão alterada. [] OBSERVAÇÕES ----- Você deve compreender as implicações da utilização do comando 'git rebase' em um repositório que você compartilha. Consulte também SE RECUPERANDO DA RECONSTRUÇÃO DA FUNDAÇÃO INICIAL (UPSTREM REBASE) abaixo. Quando o comando 'git rebase' é executado, ele primeiro executa um gancho "pre-rebase", caso exista. Você pode usar este gancho para fazer as verificações de sanidade e rejeitar a nova reconstrução, caso não seja apropriado. Consulte o modelo do script do gancho 'pre-rebase' para ter um exemplo. Após a conclusão, o <ramo> será o ramo atual. MODO INTERATIVO --------------- Reconstruir de forma interativa significa ter a chance de editar os commits que são reconstruídos. É possível reordenar os commits e removê-los (eliminando os patches ruins ou indesejados). O modo interativo é destinado para este tipo de fluxo de trabalho: 1. tenho uma ideia maravilhosa 2. hackear o código 3. preparar uma série para envio 4. enviar onde o ponto 2. consiste em várias instâncias do a) uso regular 1. termine algo digno de um commit 2. commit b) correção independente 1. perceber que algo não funciona 2. conserte isso 3. faça o commit Às vezes, a coisa fixada em b.2. não pode ser alterado para o commit nem tão perfeito que ele corrige, porque este commit está enterrado profundamente em uma série de correções. É exatamente para isso que a reconstrução interativa serve: use-o após muitos "a" e "b", reorganizando e editando os commits e comprimindo vários commits em um. Inicie-o com o último commit que você quer manter como está: git rebase -i <após-este-commit> Um editor será acionado com todos os commits no seu ramo atual (ignorando a mesclagem dos commits), que vêm após o commit informado. Você pode reordenar os commits nesta lista para o conteúdo do seu coração e pode removê-los. A lista é mais ou menos assim: ------------------------------------------- pick deadbee Uma linha deste commit pick fa1afe1 Uma linha do próximo commit ... ------------------------------------------- As descrições on-line são puramente para o seu prazer; o comando 'git rebase' não examinará eles, porém os nomes dos commits ("deadbee" e "fa1afe1" neste exemplo), portanto, não exclua ou edite os nomes. Ao substituir o comando "pick" pelo comando "edit", é possível dizer ao comando 'git rebase' para parar após aplicar este commit, para que seja possível editar os arquivos e/ou a mensagem do commit, alterar o commit e continuar com a reconstrução. Para interromper um "rebase" (exatamente como um comando "edit" faria, mas sem fazer uma escolha seletiva de nenhum commit primeiro), use o comando "break". Caso apenas queira editar a mensagem do commit para um commit, substitua o comando `pick` pelo comando `reword`. Para eliminar um commit, substitua o comando "pick" por "drop" ou apenas exclua a linha coincidente. Caso queira dobrar dois ou mais commits em um, substitua o comando "pick" da segunda e os commits subsequentes por "squash" ou "fixup". Caso os commits tenham autores diferentes, o commit dobrado será atribuído ao autor do primeiro commit. A mensagem do commit sugerido para o commit que foi dobrado é a concatenação das mensagens dos commits do primeiro commit e daquelas feitas com o comando "squash", porém omite as mensagens dos commits feitas com o comando "fixup". O comando 'git rebase' será interrompido quando o "pick" for substituído por "edit" ou quando um comando falhar devido aos erros da mesclagem. Quando você terminar de editar e/ou resolver os conflitos, será possível continuar utilizando `git rebase --continue`. Como por exemplo, caso você queira reordenar os últimos 5 commits de maneira onde o que era `HEAD~4` se torne o novo `HEAD`. Para conseguir isso, você chamaria o comando 'git rebase' assim: ---------------------- $ git rebase -i HEAD~5 ---------------------- E mova o primeiro patch para o ramo da lista. Convém recriar a mesclagem dos commits, por exemplo, caso tenha um histórico como este: ------------------ X \ A---M---B / ---o---O---P---Q ------------------ Suponha que queira reconstruir o lado do ramo ao lado começando em "A" para "Q". Verifique se o `HEAD` atual é "B" e chame ----------------------------- $ git rebase -i -r --onto Q O ----------------------------- Reordenando e editando os commits geralmente cria etapas intermediárias não testadas. Convém verificar se a edição do seu histórico não quebrou nada durante a execução de um teste ou, pelo menos, recompilando em pontos intermediários do histórico utilizando o comando "exec" (atalho "x"). Você pode fazer isso criando uma lista de tarefas como esta: ------------------------------------------- pick deadbee Implement feature XXX fixup f1a5c00 Fix to feature XXX exec make pick c0ffeee The oneline of the next commit edit deadbab The oneline of the commit after exec cd subdir; make test ... ------------------------------------------- A reconstrução interativa será interrompida quando um comando falhar (ou seja, encerra com uma condição diferente de 0) oferecendo uma oportunidade para a correção do problema. Você pode continuar com o comando `git rebase --continue`. O comando "exec" inicia o comando em um shell (aquele definido em `$SHELL`, ou o shell predefinido caso `$SHELL` não esteja definido), para que você possa utilizar os recursos do shell (como "cd", ">", ";" ...). O comando é executado a partir da raiz da árvore de trabalho. ---------------------------------- $ git rebase -i --exec "make test" ---------------------------------- Este comando permite verificar se os commits intermediários são compiláveis. A lista de tarefas fica assim: -------------------- pick 5928aea one exec make test pick 04d0fda two exec make test pick ba46169 three exec make test pick f4593f9 four exec make test -------------------- DIVIDINDO OS COMMITS --------------------- No modo interativo, é possível marcar os commits com a ação "editar". No entanto, isso não significa necessariamente que o comando 'git rebase' espere que o resultado dessa edição seja exatamente um commit. Na verdade, é possível desfazer o commit ou adicionar outros. Isso pode ser utilizado para dividir um commit em dois: - Inicie uma reconstrução interativa com `git rebase -i <commit>^`, onde <commit> é o que você quer dividir. De fato, qualquer intervalo do commit serve, desde que contenha aquele commit. - Marque o commit que deseja dividir com a ação "edit". - Quando se trata de editar este commit, execute o comando `git reset HEAD^`. O efeito é que o `HEAD` é retrocedido por um e o índice segue o conjunto. No entanto, a árvore de trabalho permanece a mesma. - Agora adicione as alterações ao índice que você queira ter no primeiro commit. Você pode utilizar o comando `git add` (possivelmente de forma interativa) ou o comando 'git gui' (ou ambos) para fazer isso. - Faça o commit do índice agora atual com qualquer mensagem do commit que seja apropriada. - Repita as duas últimas etapas até que a sua árvore de trabalho esteja limpa. - Continue a reconstrução com `git rebase --continue`. Caso não tenha certeza absoluta que as revisões intermediárias são consistentes (elas compilam, passam no conjunto de testes, etc.), você deve usar o `git stash` para ocultar o commit das alterações que ainda não foram feitas após cada commit, teste e a alteração do commit caso as correções sejam necessárias. SE RECUPERANDO DA RECONSTRUÇÃO DA FUNDAÇÃO INICIAL (UPSTREM REBASE) ------------------------------------------------------------------- Fazer a reconstrução da fundação (ou qualquer outra forma de reescrita) de um ramo onde outras pessoas tem a base de trabalho é uma péssima ideia: qualquer um que baixe dela é forçado a corrigir manualmente o seu histórico. Esta seção explica como fazer a correção do ponto de vista de quem baixou. A solução real, no entanto em primeiro lugar, seria evitar fazer a reconstrução da fundação de quem subiu (upstream). Para ilustrar, suponha que esteja em uma situação onde alguém desenvolva um ramo de um 'subsystem' e esteja trabalhando em um 'topic' que depende desse 'subsistema'. Você pode acabar com um histórico como este: ------------ o---o---o---o---o---o---o---o master \ o---o---o---o---o subsystem \ *---*---* topic ------------ Caso a reconstrução da fundação do 'subsystem' seja realizada contra o 'master', o seguinte acontece: ------------ o---o---o---o---o---o---o---o master \ \ o---o---o---o---o o'--o'--o'--o'--o' subsystem \ *---*---* topic ------------ Caso agora continue o desenvolvimento normalmente e eventualmente mescle o 'topic' para 'subsystem', os commits do 'subsystem' permanecerão duplicados para sempre: ------------ o---o---o---o---o---o---o---o master \ \ o---o---o---o---o o'--o'--o'--o'--o'--M subsystem \ / *---*---*-..........-*--* topic ------------ Geralmente, essas duplicatas são desaprovadas porque desordenam a história, dificultando o acompanhamento. Para organizar as coisas, é necessário transplantar os commits no 'topic' para o novo cume do 'subsystem', ou seja, reconstruir (rebase) o 'topic'. Isso se torna um efeito cascata: qualquer um que baixe do 'topic' é forçado a reconstruir (rebase) também e por aí vai! Existem dois tipos de correções, discutidos nas seguintes subseções: Caso fácil: as alterações são literalmente as mesmas.:: Isso acontece caso a reconstrução do 'subsystem' foi uma reconstrução simples e não houve conflitos. Caso difícil: as alterações não são as mesmas.:: Isso acontece caso a reconstrução da fundação (rebase) do 'subsistema' tiver conflitos ou utilizar o `--interactive` para omitir, editar, esmagar ou consertar consertos; ou se a inicial utilizou um dos comandos `commit --amend`, `reset` ou um histórico completo da reescrita como https://github.com/newren/git-filter-repo[`filter-repo`]. O caso fácil ~~~~~~~~~~~~ Funciona apenas se as alterações (IDs do patch com base no conteúdo do diff) no 'subsystem' que forem literalmente as mesmas antes e depois da reconstrução do 'subsystem'. Nesse caso, a correção é fácil porque o comando 'git rebase' sabe ignorar as alterações que já estão presentes no novo 'upstream' (a menos que `--reapply-cherry-picks` seja utilizada). Então, se você diz (supondo que você esteja no 'topic') ------------ $ git rebase subsystem ------------ você vai acabar com o histórico fixo ------------ o---o---o---o---o---o---o---o master \ o'--o'--o'--o'--o' subsystem \ *---*---* topic ------------ O caso difícil ~~~~~~~~~~~~~~ As coisas ficam mais complicadas caso as alterações do "subsistema" não coincidam de forma exata aquelas antes da reconstrução. NOTE: Embora uma "recuperação fácil dos casos" às vezes pareça ser bem-sucedida mesmo no caso difícil, pode haver consequências não intencionais. Para Por exemplo, um commit que foi removido através do comando `git rebase --interactive` será **ressuscitado**! A ideia é dizer manualmente ao comando 'git rebase' "onde o 'subsistema' antigo terminou e o seu 'tópico' começou", ou seja, qual era a base da mesclagem antiga entre eles. Você precisará encontrar uma maneira de nomear o último commit do antigo 'subsistema', por exemplo: * Com o 'subsistema' reflog: depois de 'git fetch', o antigo cume do 'subsistema' fica em `subsystem@{1}`. As capturas subsequentes aumentarão este número. (Consulte git-reflog[1].) * Em relação ao cume do 'topic': sabendo que o seu 'topic' tem três commits, o cume antigo do 'subsystem' deve ser `topic~3`. Você pode então transplantar o antigo `subsystem..topic` para o novo cume dizendo (para o caso do reflog e supondo que você já esteja no 'topic'): ------------ $ git rebase --onto subsystem subsystem@{1} ------------ O efeito cascata de uma recuperação "difícil" (hard case) é especialmente ruim: 'todos' baixaram do 'topic' e agora terão que executar também uma reconstrução "difícil"! RECONSTRUINDO AS MESCLAGENS --------------------------- O comando de reconstrução interativa foi originalmente projetado para lidar com séries de patches individuais. Como tal, faz sentido excluir a mesclagem dos commits da lista de tarefas, pois o desenvolvedor pode ter mesclado o `master` atual enquanto trabalhava no ramo, apenas para redefinir todos os commits para `master` eventualmente (ignorando a mesclagem dos commits). No entanto, existem razões legítimas pelas quais um desenvolvedor pode querer recriar as mesclagens dos commits: para manter a estrutura do ramo (ou a "topologia do commit") ao trabalhar em diversos ramos inter-relacionadas. No exemplo a seguir, o desenvolvedor trabalha em um tópico no ramo que refatora a maneira como os botões são definidos, em outro tópico do ramo que utilize esta refatoração para implementar um botão "Relatar um bug". A saída do `git log --graph --format=%s -5` pode ficar assim: ------------ * Mescla o ramo 'report-a-bug' |\ | * Adiciona o botão de feedback * | Mescla o ramo 'refactor-button' |\ \ | |/ | * Utiliza a classe do Botão para todos os botões | * Extrai o botão genérico do DownloadButton ------------ O desenvolvedor pode querer redefinir estes commits para um novo `master` enquanto mantém a topologia da ramificação. Quando se espera que o primeiro tópico do ramo que seja integrado ao` master` muito antes do segundo por exemplo. Para resolver os conflitos da mesclagem com as alterações para a classe `DownloadButton` que a transformou em `master` por exemplo. Esta reconstrução pode ser realizada utilizando a opção `--rebase-merges`. Ele irá gerar uma lista de tarefas, assim: ------------ rotular para # Branch: refactor-button reset onto pick 123456 Extrai o botão genérico do DownloadButton pick 654321 Utiliza a classe do Botão para todos os botões label refactor-button # Branch: report-a-bug reset refactor-button # Utiliza a classe do Botão para todos os botões pick abcdef Adiciona o botão de feedback label report-a-bug reset onto merge -C a1b2c3 refactor-button # Mescla o 'refactor-button' merge -C 6f5e4d report-a-bug # Mescla o 'report-a-bug' ------------ Ao contrário de uma reconstrução interativa regular, existem os comandos `label`, `reset` e `merge` além dos comandos `pick`. O comando `label` associa um rótulo ao `HEAD` atual quando este comando for executado. Estes rótulos são criados como refs locais da árvore de trabalho (`refs/rewritten/<label>`) que serão excluídos quando a reconstrução terminar. Dessa forma, as operações da reconstrução em várias árvores de trabalho vinculadas ao mesmo repositório não interferem entre si. Caso o comando `label` falhe, este é imediatamente reagendado, com uma mensagem útil sobre como proceder. O comando `reset` redefine o `HEAD`, o índice e a árvore de trabalho para a revisão específica. É semelhante a um comando `exec git reset --hard <label>`, porém se recusa a sobrescrever os arquivos que não sejam monitorados. Se o comando `reset` falhar, ele será imediatamente reagendado, com uma mensagem útil sobre como editar a lista de tarefas (normalmente acontece quando um comando `reset` foi inserido manualmente na lista de tarefas e contém um erro de digitação). O comando `merge` mesclará revisões especificadas no que seja `HEAD` naquele momento. Com `-C <original-commit>`, a mensagem do commit de um determinada mesclagem será usada. Quando o `C` é alterado para minúsculo `-c`, a mensagem será aberta em um editor após uma mesclagem bem-sucedida, para que o usuário possa edita-lá. Caso um comando `merge` falhar por qualquer motivo que não seja um conflito da mesclagem (ou seja, quando a operação da mesclagem sequer iniciou), ele será reagendado imediatamente. Neste momento, o comando `merge` *sempre* utilizará a estratégia da mesclagem `recursiva` para as mesclagens regulares, e `octopus` para mesclagens "polvo", sem nenhuma maneira de escolher uma diferente. Para contornar isso, um comando `exec` pode ser utilizado para chamar o comando `git merge` de forma explicita, utilizando o fato onde os rótulos são as 'refs' locais da área de trabalho (o ref `refs/rewritten/onto` corresponderia ao rótulo `onto` , por exemplo). Observação: o primeiro comando (`label onto`) rotula a revisão onde os commits são refeitos; O nome `onto` é apenas uma convenção, como um aceno para a opção `--onto`. Também é possível introduzir commits para mesclagem completamente novos, adicionando um comando no formato `merge <merge-head>`. Este formulário gera uma mensagem de commit provisória e sempre abre um editor para permitir que o usuário a edite. Pode ser útil quando por exemplo, um ramo de um tópico acaba resolvendo mais de um problema e quer ser dividido em dois ou mais ramos de tópico. Considere esta lista de tarefas: ------------ pick 192837 Alterna do GNU Makefiles para o CMake pick 5a6c7e Documente a alteração para o CMake pick 918273 Corrija a detecção do OpenSSL no CMake pick afbecd http: adicione a compatibilidade com o TLS v1.3 pick fdbaec Corrija a detecção da cURL no CMake no Windows ------------ O único commit nesta lista que não está relacionado ao CMake pode muito bem ter sido motivado ao trabalhar na correção de todos os erros introduzidos durante a mudança para o CMake, porém ele lida com um interesse diferente. Para dividir esse ramo em dois tópicos, a lista de tarefas pode ser editada desta maneira: ------------ rotular para escolha afbecd http: adicione a compatibilidade para o TLS v1.3 label tlsv1.3 redefinir para pick 192837 Alterna do GNU Makefiles para o CMake pick 918273 Corrija a detecção do OpenSSL no CMake pick fdbaec Corrija a detecção da cURL no CMake no Windows pick 5a6c7e Documente a alteração para o CMake label cmake reset onto merge tlsv1.3 merge cmake ------------ BUGS ---- A lista de tarefas apresentada pela opção descontinuada `--preserve-merges --interactive` não representa a topologia do grafo da revisão (em vez disso use a opção `--rebase-merges`). A edição dos commits e a reformulação das suas mensagens devem funcionar bem, porém as tentativas de reordenar os commits tendem a produzir resultados contra-intuitivos. Em vez disso, use a opção `--rebase-merges` em tais cenários. Por exemplo, uma tentativa para reorganizar ------------ 1 --- 2 --- 3 --- 4 --- 5 ------------ para ------------ 1 --- 2 --- 4 --- 3 --- 5 ------------ movendo a linha "pick 4" resultará no seguinte histórico: ------------ 3 / 1 --- 2 --- 4 --- 5 ------------ GIT --- Parte do conjunto git[1]