Como remover inputs de log de confirmação selecionadas de um repository Git enquanto mantém suas alterações?

Gostaria de remover inputs de log de confirmação selecionadas de uma tree de confirmação linear, para que as inputs não sejam exibidas no log de confirmação.

Minha tree de commits é algo como:

R--A--B--C--D--E--HEAD 

Gostaria de remover as inputs B e C para que elas não sejam exibidas no log de confirmação, mas as alterações de A para D devem ser preservadas. Talvez introduzindo um único commit, para que B e C se tornem BC e a tree pareça.

 R--A--BC--D--E--HEAD 

Ou, idealmente, depois de A vem D diretamente. D ‘representando mudanças de A para B, B para C e C para D.

 R--A--D'--E--HEAD 

Isso é possível? se sim, como?

Este é um projeto relativamente novo, portanto, não possui ramificações a partir de agora, portanto, não há mesclagem também.

git-rebase (1) faz exatamente isso.

 $ git rebase -i HEAD~5 

git awsome-ness [git rebase – interativo] contém um exemplo.

  1. Não use o git-rebase em commits públicos (remotos).
  2. Certifique-se de que seu diretório de trabalho esteja limpo ( commit ou commit suas alterações atuais).
  3. Execute o comando acima. Ele lança seu $EDITOR .
  4. Substitua pick antes de C e D por squash . Ele vai fundir C e D em B. Se você quiser excluir um commit, basta excluir sua linha.

Se você estiver perdido, digite:

 $ git rebase --abort 
 # detach head and move to D commit git checkout  # move HEAD to A, but leave the index and working tree as for D git reset --soft  # Redo the D commit re-using the commit message, but now on top of A git commit -C  # Re-apply everything from the old D onwards onto this new place git rebase --onto HEAD  master 

Aqui está uma maneira de remover um ID de confirmação específico, conhecendo apenas o ID de confirmação que você gostaria de remover.

 git rebase --onto commit-id^ commit-id 

Observe que isso realmente remove a alteração que foi introduzida pela confirmação.

Para expandir a resposta de JF Sebastian:

Você pode usar o git-rebase para fazer facilmente todos os tipos de alterações em seu histórico de commits.

Depois de executar o git rebase –interactive, você obtém o seguinte no seu $ EDITOR:

 pick 366eca1 This has a huge file pick d975b30 delete foo pick 121802a delete bar # Rebase 57d0b28..121802a onto 57d0b28 # # 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 

Você pode mover linhas para alterar a ordem de confirmações e excluir linhas para remover essa confirmação. Ou você pode adicionar um comando para combinar (squash) dois commits em um único commit (commit anterior é o commit acima), edit commits (o que foi alterado), ou rewrite mensagens de commit.

Acho que escolher significa apenas que você quer deixar esse compromisso sozinho.

(Exemplo é daqui )

Você pode remover interativamente B e C em seu exemplo com:

 git rebase --onto HEAD~5 HEAD~3 HEAD 

ou simbolicamente

 git rebase --onto AC HEAD 

Note que as mudanças em B e C não estarão em D; eles terão ido embora .

Eu acho este processo muito mais seguro e mais fácil de entender, criando outro ramo a partir do SHA1 de A e escolhendo as mudanças desejadas para que eu possa ter certeza de como esta nova ramificação se parece. Depois disso, é fácil remover a ramificação antiga e renomear a nova.

 git checkout  git log #verify looks good git checkout -b rework git cherry-pick  .... git log #verify looks good git branch -D  git branch -m rework  

Mais uma maneira,

 git rebase -i ad0389efc1a79b1f9c4dd6061dca6edc1d5bb78a (C's hash) and git push origin master -f 

escolha o hash que você quer usar como base, e o comando acima deve torná-lo interativo para que você possa esmagar todas as mensagens principais (você precisa deixar as mais antigas)

Recolheu apenas as respostas de todas as pessoas: (m novo para git plz usá-lo apenas para referência)

git rebase para excluir qualquer commit

log do git

 -first check from which commit you want to rebase 

git rebase -i CABEÇA ~ 1

 -Here i want to rebase on the second last commit- commit count starts from '1') -this will open the command line editor (called vim editor i guess) 

Então a canvas será algo como isto:

escolha 0c2236d Adicionado nova linha.

Rebase 2a1cd65..0c2236d em 2a1cd65 (1 comando)

#

Comandos:

p, pick = use commit

r, reword = use commit, mas edite a mensagem de commit

e, edit = use commit, mas pare por alterar

s, squash = usa commit, mas combina com commit anterior

f, fixup = like “squash”, mas descarta a mensagem de log deste commit

x, exec = executa o comando (o resto da linha) usando shell

d, drop = remove commit

#

Essas linhas podem ser reordenadas; eles são executados de cima para baixo.

#

Se você remover uma linha aqui QUE COMITAR SERÁ PERDIDA.

#

No entanto, se você remover tudo, o rebase será abortado.

#

Observe que os commits vazios são comentados ~ ~

~
~
~
~
~
~
~
~
~

Aqui mude a primeira linha conforme sua necessidade (usando os comandos listados acima, ie ‘drop’ para remover commit, etc.). Uma vez feita a edição, pressione ‘: x’ para salvar e sair do editor (isto é somente para o editor vim)

E depois

git push

Se o seu problema de exibição, então você precisa empurrar com força as mudanças para o remoto (ITS muito crítico: não force empurrar se você estiver trabalhando em equipe)

git push -f origem

Você pode usar o git cherry-pick para isso. ‘cherry-pick’ aplicará um commit no branch seu agora.

então faça

 git rebase --hard  

em seguida, aplique os commits D e E.

 git cherry-pick  git cherry-pick  

Isso irá ignorar o commit B e C. Tendo dito que pode ser impossível aplicar o D commit ao branch sem B, então YMMV.