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:
git reset HEAD^
O git reset
sem --hard
ou --soft
move seu HEAD
para apontar para o commit especificado, sem alterar nenhum arquivo. O HEAD^
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:
git commit --amend [-m … etc]
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
.
git reset HEAD^
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.
git config --global alias.uncommit 'reset HEAD^'
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.
git rebase -i <ref>
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-chave squash
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.
git stash save 'some message'
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...
git stash list
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...
git stash apply stash@{#}
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.
git stash
git checkout <correct_branch>
git stash apply
No seu caso você se moveu um pouco mais pelos galhos, mas a mesma idéia ainda se aplica.
Espero que isto ajude.