Posso apagar um compromisso de git mas manter as alterações
Em um dos meus ramos de desenvolvimento, fiz algumas mudanças na minha base de código. Antes de poder completar as funcionalidades em que estava a trabalhar, tive de mudar o meu ramo actual para o master para fazer uma demonstração de algumas funcionalidades. Mas usando apenas um "git checkout master" preservei as alterações que também fiz no meu ramo de desenvolvimento, quebrando assim algumas das funcionalidades do master. Então o que eu fiz foi submeter as alterações no meu ramo de desenvolvimento com uma mensagem de commit " commit" temporário; e depois checkout master para o demo.
Agora que eu'estou pronto com a demonstração e de volta ao trabalho no meu ramo de desenvolvimento, gostaria de remover o "commit" temporário; que eu fiz enquanto ainda preservava as mudanças que eu fiz. Isso é possível?
It's tão simples como isto:
O
git reset
sem--hard
ou--soft
move seuHEAD
para apontar para o commit especificado, sem alterar nenhum arquivo. OHEAD^
refere-se ao (primeiro) commit pai do seu commit atual, que no seu caso é o commit antes do commit temporário.Note que outra opção é continuar como normalmente, e depois no próximo ponto de compromisso, em vez disso, executar:
que, em vez disso, editará o compromisso mais recente, tendo o mesmo efeito que acima.
Note que isto (como em quase todas as respostas idiota) pode causar problemas se você'já empurrou o mau compromisso para um lugar de onde outra pessoa pode tê-lo tirado. Tente evitar que
Há duas maneiras de lidar com isto. O que é mais fácil depende da sua situação
**Reset***
Se o compromisso do qual você quer se livrar foi o último compromisso, e você não fez nenhum trabalho adicional você pode simplesmente usar o
git-reset
.Leva a sua filial de volta ao compromisso pouco antes da sua actual CABEÇA. Entretanto, ele não'na verdade não muda os arquivos na sua árvore de trabalho. Como resultado, as alterações que estavam naquele commit aparecem como modificadas - é como um comando 'uncommit'uncommit'. Na verdade, eu tenho um alias para fazer exatamente isso.
Então você pode apenas utilizar o "git uncommit" no futuro para apoiar um compromisso.
**Squashing***
Esmagar um commit significa combinar dois ou mais commits em um. Eu faço isto com bastante frequência. No seu caso, você tem uma característica comprometida pela metade, e então você a terminaria e se comprometeria novamente com a mensagem de compromisso permanente apropriada.
Eu digo acima porque eu quero deixar claro que isto pode ser qualquer número de compromissos de volta. Execute
git log
e encontre o commit que você quer se livrar, copie seu SHA1 e use-o no lugar de. Git irá levá-lo para o modo rebase interativo. Ele mostrará todos os commits entre o seu estado atual e o que você colocar no lugar de
. Então se `` for 10 commits atrás, ele mostrará todas as 10 commits.Na frente de cada compromisso, terá a palavra "escolher". Encontre o commit que você quer se livrar e mude-o de "pegar" para "consertar" ou "esmagar". Utilizando
fixup
simplesmente descarta a mensagem de commit e funde as alterações no seu predecessor imediato na lista. A palavra-chavesquash
faz a mesma coisa, mas permite que você edite a mensagem de commit da nova submissão combinada.Note que os commits serão novamente comprometidos na ordem em que aparecem na lista quando você sair do editor. Então se você fez um commit temporário, então fez outro trabalho no mesmo ramo, e completou o recurso em um commit posterior, então usar o rebase permitiria que você reordenasse os commits e os esmagasse.
AVISO:
Rebase modifica a história - NÃO faça isso para qualquer compromisso que você já tenha compartilhado com outros desenvolvedores.
**Abrilho***
No futuro, para evitar este problema, considere a utilização do
git stash
para armazenar temporariamente trabalhos não comprometidos.Isto irá armazenar as suas alterações actuais no lado da sua lista de compras. Acima está a versão mais explícita do comando stash, permitindo um comentário para descrever o que você está armazenando. Você também pode simplesmente executar
git stash
e nada mais, mas nenhuma mensagem será armazenada.Podes procurar na tua lista de esconderijo com...
Isto irá mostrar-lhe todos os seus stashes, em que ramos foram feitos, e a mensagem e no início de cada linha, e identificador para aquele stash que se parece com este
stash@{#}
onde # é a sua posição na matriz de stashes.Para restaurar um esconderijo (o que pode ser feito em qualquer ramo, independentemente de onde o esconderijo foi originalmente criado) você simplesmente corre...
Mais uma vez, há # a posição no conjunto de esconderijos. Se o stash que você quer restaurar está na posição
0
- ou seja, se foi o stash mais recente. Então você pode simplesmente executar o comando sem especificar a posição do stash, git irá assumir que você quer dizer a última:git stash apply
.Então, por exemplo, se eu me encontrar trabalhando no ramo errado - eu posso executar a seguinte seqüência de comandos.
No seu caso você se moveu um pouco mais pelos galhos, mas a mesma idéia ainda se aplica.
Espero que isto ajude.
Mais uma maneira de o fazer.
Adicione commit no topo do commit temporário e depois faça:
Para fundir dois commits em um (o comando abrirá um arquivo de texto com instruções explícitas, edite-o).