Eu acidentalmente comprometido com o ramo errado. Como faço para excluir essa confirmação?
Eu acidentalmente comprometido com o ramo errado. Como faço para excluir essa confirmação?
Respostas:
Exclua a confirmação mais recente, mantendo o trabalho que você fez:
git reset --soft HEAD~1
Exclua a confirmação mais recente, destruindo o trabalho que você fez:
git reset --hard HEAD~1
git reset --hard origin
git remote
lista a origem para mim, git reset --hard origin
diz fatal: ambiguous argument 'origin': unknown revision or path not in the working tree.
. Por quê?
git reset HEAD~1
também manterá todas as suas alterações, mas o deixará com um índice vazio, em vez de manter tudo (como a --soft
opção faria).
Eu me pergunto por que a melhor resposta que eu encontrei é apenas nos comentários! ( por Daenyth com 86 votos a favor )
git reset --hard origin
Este comando sincronizará o repositório local com o repositório remoto, livrando-se de todas as alterações feitas no seu local. Você também pode fazer o seguinte para buscar o ramo exato que possui na origem.
git reset --hard origin/<branch>
git reset --hard origin/<branch>
git reset --soft origin/<branch>
, se você quiser se livrar da confirmação, mas mantenha o trabalho local.
fatal: ambiguous argument 'origin': unknown revision or path not in the working tree.
, você precisa especificar o ramo como:git reset --hard origin/feature/my-cool-stuff
Não exclua: apenas uma confirmação git cherry-pick
é suficiente.
Mas se você teve vários commits no branch errado, é aí que git rebase --onto
brilha:
Suponha que você tenha o seguinte:
x--x--x--x <-- master
\
-y--y--m--m <- y branch, with commits which should have been on master
, então você pode marcar master
e movê-lo para onde você deseja estar:
git checkout master
git branch tmp
git checkout y
git branch -f master
x--x--x--x <-- tmp
\
-y--y--m--m <- y branch, master branch
, redefina o ramo onde deveria estar:
git checkout y
git reset --hard HEAD~2 # ~1 in your case,
# or ~n, n = number of commits to cancel
x--x--x--x <-- tmp
\
-y--y--m--m <- master branch
^
|
-- y branch
e, finalmente, mova seus commits (reaplique-os, fazendo realmente novos commits)
git rebase --onto tmp y master
git branch -D tmp
x--x--x--x--m'--m' <-- master
\
-y--y <- y branch
Se você deseja mover esse commit para outro ramo, obtenha o SHA do commit em questão
git rev-parse HEAD
Em seguida, alterne o ramo atual
git checkout other-branch
E cherry-pick
o compromisso deother-branch
git cherry-pick <sha-of-the-commit>
git reset --hard HEAD~1
posterior. Eu acho que usar a reset --soft
troca de ramificações e confirmar novamente teria economizado trabalho extra. Então, novamente, eu estava usando o SourceTree para fazer a maioria das minhas coisas básicas, apenas alinhando-o com isso após o meu erro.
Para sua referência, acredito que você pode "cortar com força" as confirmações de sua ramificação atual, não apenas com git reset --hard, mas também com o seguinte comando:
git checkout -B <branch-name> <SHA>
De fato, se você não se importa com o check-out, pode definir o ramo para o que quiser com:
git branch -f <branch-name> <SHA>
Essa seria uma maneira programática de remover confirmações de uma ramificação, por exemplo, para copiar novas confirmações para ela (usando rebase).
Suponha que você tenha uma ramificação desconectada do mestre porque você pegou fontes de algum outro local e as despejou na ramificação.
Agora você tem um ramo no qual aplicou alterações, vamos chamá-lo de "tópico".
Agora você criará uma duplicata do seu ramo de tópico e depois o rebatizará no dump do código-fonte que está localizado no ramo "dump":
git branch topic_duplicate topic
git rebase --onto dump master topic_duplicate
Agora, suas alterações são reaplicadas no ramo topic_duplicate, com base no ponto inicial de "dump", mas apenas nos commits que ocorreram desde o "master". Portanto, suas alterações desde o mestre agora são reaplicadas em cima de "dump", mas o resultado acaba em "topic_duplicate".
Você pode substituir "dump" por "topic_duplicate" fazendo o seguinte:
git branch -f dump topic_duplicate
git branch -D topic_duplicate
Ou com
git branch -M topic_duplicate dump
Ou apenas descartando o lixo
git branch -D dump
Talvez você também possa escolher depois de limpar o atual "topic_duplicate".
O que estou tentando dizer é que, se você deseja atualizar o ramo "duplicado" atual com base em um ancestral diferente, você deve primeiro excluir os commits "cherrypicked" anteriormente fazendo um git reset --hard <last-commit-to-retain>
ou git branch -f topic_duplicate <last-commit-to-retain>
e depois copiando os outros commits over (a partir do main ramificação de tópico) rebasing ou cherry-picking.
A rebasagem funciona apenas em uma ramificação que já possui confirmações, portanto, você deve duplicar sua ramificação de tópico sempre que desejar fazer isso.
Cherrypicking é muito mais fácil:
git cherry-pick master..topic
Portanto, toda a sequência se resume a:
git reset --hard <latest-commit-to-keep>
git cherry-pick master..topic
Quando o seu ramo duplicado de tópico tiver sido retirado. Isso removeria confirmações escolhidas anteriormente pela cereja do duplicado atual e apenas reaplicaria todas as alterações que aconteciam no "tópico", além do seu "despejo" atual (ancestral diferente). Parece uma maneira razoavelmente conveniente de basear seu desenvolvimento no mestre upstream "real" enquanto usa um mestre "downstream" diferente para verificar se suas alterações locais também se aplicam a isso. Como alternativa, você pode gerar um diff e aplicá-lo fora de qualquer árvore de fontes Git. Mas, dessa maneira, você pode manter uma versão modificada (corrigida) atualizada, baseada na versão da sua distribuição enquanto o seu desenvolvimento real é contra o verdadeiro mestre upstream.
Então, apenas para demonstrar:
Espero que isso ajude alguém. Eu pretendia reescrever isso, mas não posso gerenciar agora. Saudações.
O comando a seguir funcionou para mim, todas as alterações confirmadas locais são descartadas e o local é redefinido para o mesmo que origem remota / ramificação mestre.
origem do git reset --hard