Conheci minha história e quero fazer algumas alterações. O problema é que tenho um commit com duas alterações não relacionadas, e esse commit está cercado por outras alterações no meu histórico local (não enviado por push).
Quero dividir esse commit antes de enviá-lo, mas a maioria dos guias que vejo estão relacionados à divisão do commit mais recente ou das alterações locais não confirmadas. É possível fazer isso com um commit que está um pouco enterrado na história, sem ter que "refazer" meus commits desde então?
Respostas:
Há um guia para dividir confirmações na página de manual rebase . O resumo rápido é:
Execute uma nova reformulação interativa, incluindo o commit de destino (por exemplo
git rebase -i <commit-to-split>^ branch
) e marque-o para ser editado.Quando o rebase atingir esse commit, use
git reset HEAD^
para redefinir para antes do commit, mas mantenha sua árvore de trabalho intacta.Adicione alterações de forma incremental e as confirme, fazendo o número de confirmações desejadas.
add -p
pode ser útil adicionar apenas algumas das alterações em um determinado arquivo. Usecommit -c ORIG_HEAD
se desejar reutilizar a mensagem de confirmação original para uma determinada confirmação.Se você quiser testar o que está comprometendo (boa ideia!)
git stash
Para ocultar a parte que não foi comprometida (oustash --keep-index
antes mesmo de executá-la), teste e, em seguida,git stash pop
retorne o restante para a árvore de trabalho. Continue fazendo confirmações até obter todas as modificações confirmadas, ou seja, tenha uma árvore de trabalho limpa.Execute
git rebase --continue
para continuar aplicando as confirmações após a confirmação agora dividida.fonte
git rebase -i <sha1_of_the_commit_to_split>^ branch
. Egit gui
é uma boa ferramenta para a tarefa de divisão, que pode ser usada para adicionar diferentes partes de um arquivo em diferentes confirmações.git add -p
, que pode fazer mais do quegit gui
pode neste departamento (notavelmente editando pedaços, organizando tudo a partir do pedaço atual e procurando pedaços por expressão regular).Veja como fazer isso com o Magit .
Digamos que commit ed417ae é o que você deseja alterar; ele contém duas alterações não relacionadas e está oculto sob uma ou mais confirmações. Pressione
ll
para mostrar o log e navegue para ed417ae:Em seguida, pressione
r
para abrir o pop-up rebasee
m
para modificar o commit no ponto.Observe como o
@
agora existe no commit que você deseja dividir - isso significa que HEAD está agora no commit:Queremos mover HEAD para o pai, então navegue até o pai (47e18b3) e pressione
x
(magit-reset-quickly
, vinculado ao
se você estiver usandoevil-magit
) e entre para dizer "sim, eu quis dizer confirmar no momento". Seu log agora deve se parecer com:Agora, pressione
q
para acessar o status regular do Magit, depois use ou
comando regular unstage para desestabilizar o que não ocorre no primeiro commit, comprometac
o resto como de costume, depoiss
calcule ec
omita o que ocorre no segundo commit e quando terminar: cliquer
para abrir o pop-up rebasee outro
r
para continuar, e pronto!ll
agora mostra:fonte
Para dividir uma confirmação
<commit>
e adicionar a nova confirmação antes desta , e salve a data do autor de<commit>
, - as etapas a seguir:Edite a confirmação antes
<commit>
NB: talvez também seja necessário editar
<commit>
também.Escolha cereja
<commit>
no índiceRedefina interativamente as alterações desnecessárias do índice e redefina a árvore de trabalho
Como alternativa, apenas armazene alterações desnecessárias de maneira interativa:
git stash push -p -m "tmp other changes"
Faça outras alterações (se houver) e crie o novo commit
Opcionalmente, repita os itens 2-4 para adicionar mais confirmações intermediárias.
Continuar rebaseando
fonte
Existe uma versão mais rápida se você deseja extrair o conteúdo de apenas um arquivo. É mais rápido porque o rebase interativo não é mais interativo (e, é claro, ainda mais rápido se você deseja extrair do último commit, então não há necessidade de rebase)
the_file
. Fecharthe_file
. Essa é a única edição que você precisa, todo o resto são apenas comandos git.Estágio que exclusão no índice:
Restaure as linhas que você acabou de excluir de volta no arquivo sem afetar o índice !
"SHA1" é o commit do qual você deseja extrair as linhas:
Crie a segunda confirmação totalmente nova com o conteúdo a ser extraído restaurado na etapa 3:
Não edite, não pare / continue - apenas aceite tudo:
Obviamente, ainda mais rápido quando o commit a ser extraído é o último commit:
Se você usar
magit
, as etapas 4, 5 e 6 são uma ação única: Confirmar, correção instantâneafonte
Se você ainda não pressionou, basta usar
git rebase
. Melhor ainda, usegit rebase -i
para mover confirmações de maneira interativa. Você pode mover a confirmação incorreta para a frente, depois dividi-la como quiser e mover as correções para trás (se necessário).fonte