Desfazer uma mesclagem do Git que ainda não foi enviada por push

3944

No meu ramo principal, fiz um git merge some-other-branchlocal, mas nunca forcei as alterações no mestre de origem. Não era minha intenção mesclar, então gostaria de desfazer. Ao fazer uma git statuspós-mesclagem, recebi esta mensagem:

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.

Com base em algumas instruções que encontrei , tentei executar

git revert HEAD -m 1

mas agora estou recebendo esta mensagem com git status:

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

Não quero que meu ramo esteja à frente em nenhum número de confirmações. Como eu volto a esse ponto?

Matt Huggins
fonte
3
Se você precisa preservar a história, em outras palavras, há uma mudança que alguém já retirou de você ou você a empurrou para algum lugar, use a solução na resposta de Yuri Ushakov abaixo!
Sedrik 12/10
6
Desmarque a resposta vencedora atual; ela é insegura (como muitos apontaram), embora ainda receba votos. Para mim, "MBO" -s parece melhor, embora tenha muito menos pontos.
inger
5
Se você precisar preservar a história , use a solução da Yuri abaixo ! (apenas adicionando um link para o comentário do @Sedrik)
cregox 17/09/13
3
Este é um grande recurso em linha reta do Github: Como desfazer (quase) qualquer coisa com Git
jasonleonhard

Respostas:

4460

Com a git reflogverificação de qual commit é anterior à mesclagem ( git reflogserá uma opção melhor que git log). Em seguida, você pode redefini-lo usando:

git reset --hard commit_sha

Há também outra maneira:

git reset --hard HEAD~1

Você receberá 1 commit.

Esteja ciente de que todos os arquivos modificados e não confirmados / não armazenados em cache serão redefinidos para seu estado não modificado . Para mantê-los, oculte as alterações ou veja a --mergeopção abaixo.


Como o @Velmont sugeriu abaixo em sua resposta, neste caso direto, use:

git reset --hard ORIG_HEAD

pode gerar melhores resultados, pois deve preservar suas alterações. ORIG_HEADapontará para um commit diretamente antes da mesclagem, para que você não precise procurá-lo.


Uma outra dica é usar a --mergeopção em vez de --hardnão redefinir arquivos desnecessariamente:

git reset --merge ORIG_HEAD

--merge

Redefine o índice e atualiza os arquivos na árvore de trabalho que são diferentes entre <commit> e HEAD, mas mantém aqueles que são diferentes entre o índice e a árvore de trabalho (ou seja, que apresentam alterações que não foram adicionadas).

Marcin Gil
fonte
129
Eu não acho que isso funcionará (sempre?) - o "antes da mesclagem" será o commit mais recente que foi mesclado no outro branch - não será o commit mais recente no branch atual . Direita? (Isso pode ser apenas um resultado do que git logescolhe para mostrar por padrão - talvez haja uma saída diferente de git logou git reflogpoderia ser usado para isso)
John Bachir
6
Eu acho que pode depender se você esmaga a mescla.
Marcin Gil
29
@JohnBachir está certo. Na git logsaída, você deseja observar as duas confirmações principais. Um é o último commit no seu ramo, um é o último commit no ramo no qual você mesclou. Você deseja git reset --hardconfirmar o pai na ramificação na qual você mesclou.
23711 Justin justin
7
@JohnBachir: Desde que a "mesclagem" não seja realmente um avanço rápido, isso resultará em um novo commit que está no topo do log, e esse commit terá dois pais (ou mais de 2 se você fizer um polvo) mesclar). Se você remover esse commit de mesclagem, todos os commits mais antigos que vieram da mesclagem também desaparecerão. Porém, para estar seguro, após uma redefinição, o git informará onde está o novo cabeçalho: "HEAD está agora em 88a04de <commit message>". Eu sempre olho para isso para ter certeza de que acabei onde esperava. Meu projeto usa um esquema de nomenclatura padrão para manter as coisas memoráveis.
Mark E. Haase
44
O que achei útil foi olhar para "git reflog" e procurar o último commit que fiz no master. Então façagit reset --hard <commit_sha>
Max Williams
1456

Supondo que seu mestre local não estava à frente da origem / mestre, você deve conseguir

git reset --hard origin/master

Então sua masterfilial local deve parecer idêntica a origin/master.

randomguy3
fonte
71
@Carter, na verdade, não é a melhor resposta. É possível que a origem / master pode estar à frente do seu mestre local justamente antes de a fusão por alguns commits, nesse caso isso pode não dar os resultados desejados
Dhruva Sagar
15
@ dhruva-sagar Sim, mas enquanto o git não disser que você está atrasado e não buscar, você ficará bem.
Kelvin #
3
Obrigado! Isso é perfeito se (e somente se) você tiver um repositório remoto.
tomc
2
Não, não é o ideal para esta pergunta, veja a cláusula "assumir". A resposta do MBO realmente cobre esse caso e o caso em que a mesclagem não é o único commit local.
inger
2
Mais uma vez, talvez esse aviso deva dar a resposta: sempre evite reescrever o histórico do git!
Cregox 17/09/2013
1175

Veja o capítulo 4 no livro Git e a postagem original de Linus Torvalds .

Para desfazer uma mesclagem que já foi enviada por push :

git revert -m 1 commit_hash

Não se esqueça de reverter a reversão se você estiver realizando o ramo novamente, como Linus disse.

Yuri Geinish
fonte
10
@perfectionist concordou :) Kind of gostaria que houvesse uma maneira de migrar esta resposta para outro question-- (talvez haja?)
mikermcneil
para obter mais informações sobre revert: link
assaqqaf 4/14
1
Para ter certeza de que essa reversão funcionou, você pode fazer o git diff hash1 hash2 em que hash1 é a reversão confirmada e hash2 é o commit antigo cujo estado você estava tentando voltar. Sem saída == sucesso! Consegui reverter várias confirmações fazendo isso várias vezes, começando revertendo a mesclagem mais recente e trabalhando para trás. git diff me mostrou que eu acabei no estado que eu queria.
Robert Sinton
6
Observe que isso realmente não resolve a pergunta do pôster original . O pôster original já foi usado git revert -m 1 <commit>. O problema é que isso não apaga a fusão acidental que ele fez (e ainda não fez). As outras respostas que envolvem redefinições rígidas são melhores para o problema do pôster original.
Este é um ótimo recurso direto do Github: Como desfazer (quase) qualquer coisa com o Git
jasonleonhard
986

É estranho que o comando mais simples estivesse faltando. A maioria das respostas funciona, mas desfazendo a mesclagem que você acabou de fazer, esta é a maneira mais fácil e segura :

git reset --merge ORIG_HEAD

A referência ORIG_HEADapontará para o commit original antes da mesclagem.

(O --merge opção não tem nada a ver com a mesclagem. É como git reset --hard ORIG_HEAD, mas mais seguro, pois não toca em alterações não confirmadas.)

odinho - Velmont
fonte
17
Se você sujou sua árvore de trabalho desde então, git reset --merge ORIG_HEADpreserva essas alterações.
yingted
1
Esta é a única resposta correta (não estou dizendo que esta é a melhor resposta - observe a diferença). Digamos que, no mestre, fiz 3 confirmações em t1, t3 e t5. Digamos que, no ramo 1, fiz 3 comentários em t2, t4 e t6 (suponha que t1, t2, t3, t4, t5 e t6 estejam em ordem cronológica). Qualquer comando semelhante a git reset --hard HEAD~5apenas redefinirá HEAD (pode remover confirmações no mestre e no branch1). Somente a --mergeopção remove o merge.
Manu Manjunath
@Manu A --mergeopção não remove a mesclagem, você pode usá- --hardla também funcionará bem. É a referência ORIG_HEAD que é a pista aqui; ela é definida antes de você fazer uma mesclagem para onde você está nesse ponto. :)
odinho - Velmont
@yingted, o que você quer dizer com "Se você sujou sua árvore de trabalho desde então, o git reset --merge ORIG_HEAD preserva essas alterações." Você quis dizer alterar os arquivos após a mesclagem? De qualquer forma, fiz a mesclagem e resolvi alguns conflitos. Mas então eu queria redefinir a mesclagem e fiz conforme as instruções nesta resposta. Tudo estava ok e não preservou minhas alterações feitas após a mesclagem. Meu repo local é semelhante à posição anterior à fusão.
Samitha Chathuranga
O git reset --hard ORIG_HEADcomando funcionou perfeitamente para mim - pode ter sido ajudado pelo fato de eu não fazer outras alterações no repositório após o local git mergeque estava tentando desfazer. O comando simplesmente redefine o estado do repositório para o estado anterior à mesclagem. Obrigado pela ótima dica!
bluebinary
391

Com as versões mais recentes do Git, se você ainda não confirmou a mesclagem e tem um conflito de mesclagem , basta:

git merge --abort

De man git merge:

[Isso] só pode ser executado após a mesclagem resultar em conflitos. git merge --abortinterromperá o processo de mesclagem e tentará reconstruir o estado de pré-mesclagem.

Travis Reeder
fonte
8
Sua fusão está comprometida, mas não empurrou (ver título), ele já se fundiu, o comando funciona somente quando ele ainda está no meio de uma fusão
JBoy
135

Você deve redefinir para o commit anterior. Isso deve funcionar:

git reset --hard HEAD^

Ou até mesmo HEAD^^reverter esse commit de reversão. Você sempre pode fornecer uma referência completa do SHA se não tiver certeza de quantos passos você deve seguir.

Caso você tenha problemas e sua ramificação principal não tenha alterações locais, você pode redefinir para origin/master.

MBO
fonte
5
A melhor resposta IMHO incorpora a própria do OP (assumindo apenas 1 passo para reverter, o que parecia ser o caso no Q), bem como o atalho do randomguy3 (que funciona quando "seu ramo principal não teve alterações locais ")
inger 21/03
4
Vocês comentaristas, @Inger e @Konstantin, por quê? Você veio aqui depois que minha resposta foi criada e é mais correta. Subir um passo no HEAD geralmente é errado, e você precisa contar até onde precisa ir. O Git já define ORIG_HEADpara você, por que não usá-lo?
odinho - Velmont
redefinirá as alterações locais também? #Por favor atualize.
CoDe
Isso funcionou perfeitamente para mim, redefinir a cabeça assim faz muito mais sentido do que metade das respostas aqui.
Varda Elentári 22/09/16
HEAD ^ é igual a commit antes de HEAD? e ^^ são dois commits anteriores? Achando que isso não funcionará com mesclagens de avanço rápido?
Marcus Leon
87

Ultimamente, tenho usado git reflogpara ajudar com isso. Isso geralmente funciona apenas se a mesclagem APENAS aconteceu e estava na sua máquina.

git reflog pode retornar algo como:

fbb0c0f HEAD@{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 HEAD@{1}: checkout: moving from master to my-branch
e3753a7 HEAD@{2}: rebase finished: returning to refs/heads/master
e3753a7 HEAD@{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 HEAD@{4}: reset: moving to HEAD^
8400a0f HEAD@{5}: rebase: aborting

A primeira linha indica que ocorreu uma mesclagem. A segunda linha é o tempo antes da minha mesclagem. Eu simplesmente git reset --hard 43b6032forço esse ramo a rastrear antes da mesclagem e continuar.

Parris
fonte
Ótima resposta, obrigado! Precisava desfazer uma mesclagem, mas as outras respostas apenas atrapalhavam mais, usando reflogpara obter o SHA e passar isso para o git resettrabalho.
precisa saber é o seguinte
51

Com o moderno Git, você pode:

git merge --abort

Sintaxe mais antiga:

git reset --merge

Moda antiga:

git reset --hard

Mas, na verdade, vale a pena notar que isso git merge --aborté apenas equivalente ao git reset --mergeque MERGE_HEADestá presente. Isso pode ser lido na ajuda do Git para o comando mesclar.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

Após uma mesclagem com falha, quando não há MERGE_HEAD, a mesclagem com falha pode ser desfeita git reset --merge, mas não necessariamente com git merge --abort, portanto , elas não são apenas uma sintaxe antiga e nova para a mesma coisa .

Pessoalmente, acho git reset --mergemuito mais poderoso e útil no trabalho diário, então é esse que eu sempre uso.

Martin G
fonte
Funcionou muito bem para mim. Qualquer outro post diz que isso é tão complicado, mas isso fez exatamente o que é esperado. Suponho que só funcionou porque houve conflitos, o que não responde exatamente à pergunta original.
Jeremy
Essa resposta não se concentra na situação do OP e deixa de fora um contexto importante.
Ben Wheeler
37

Ok, as respostas que outras pessoas aqui me deram foram próximas, mas não funcionou. Aqui está o que eu fiz.

Fazendo isso...

git reset --hard HEAD^
git status

... me deu o seguinte status.

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.

Eu tive que digitar o mesmo git resetcomando várias vezes. Cada vez que fiz isso, a mensagem mudou em um, como você pode ver abaixo.

> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 2 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

Nesse ponto, vi a mensagem de status alterada, então tentei fazer um git pulle isso pareceu funcionar:

> git pull
Updating 2df6af4..12bbd2f
Fast forward
 app/views/truncated |    9 ++++++---
 app/views/truncated |   13 +++++++++++++
 app/views/truncated |    2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
> git status
# On branch master

Para encurtar a história, meus comandos se resumiram a isso:

git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git pull
Matt Huggins
fonte
19
ou você poderia ter usadoHEAD^^^^
hasen
17
talvez até redefinir para origin/master;)
hasen
23

Você pode usar git reflogpara encontrar a finalização da compra anterior. Às vezes, esse é um bom estado para o qual você deseja voltar.

Concretamente,

$ git reflog
$ git reset --hard HEAD@{0}
stephjang
fonte
1
Obrigado! Você salvou meio dia do meu trabalho. No entanto, não consegui sair do modo reflog com nenhum comando.
Katarzyna
1
@Katarzyna usar a tecla "q" para sair do reflog
Amjed Baig
21

Se você estiver no meio da fusão, sempre poderá abortá-lo git merge --abort

llioor
fonte
2
obrigado mano e eu estava prestes a fazer essa coisa assustadora resposta correta. sorte eu rolei para baixo. eu só quero excluir cabeça merge
Nyuu
15

Consegui resolver esse problema com um único comando que não envolve procurar uma identificação de confirmação.

git reset --hard remotes/origin/HEAD

A resposta aceita não funcionou para mim, mas esse comando alcançou os resultados que eu estava procurando.

Ralph Ritoch
fonte
Exatamente! Ele redefine suas alterações na CABEÇA do ramo! Não fazendo um por um
Carlos Zinato 21/09
não funcionou para mim. acabou enviando a filial local de volta em um mês ou dois. Felizmente, isso é tudo local, para que eu possa sempre destruir o ramo e buscá-lo novamente. Só queria salientar isso no caso de outros tentarem isso.
precisa
@MattPengelly, esse método não é documentado e geralmente funciona se sua ramificação estiver sincronizada com a ramificação remota antes de você fazer a mesclagem. Faz meses desde que sua filial estava sincronizada com a filial remota?
Ralph Ritoch 6/06/19
@MattPengelly também depende de qual ramo o HEAD está apontado. Estou usando o gitflow em um dos meus projetos e, mesmo estando no ramo de desenvolvimento, os controles remotos / origem / HEAD são apontados para origem / mestre, portanto, se eu precisar desfazer uma mesclagem, provavelmente precisarei redefinir para controles remotos / origin / develop
Ralph Ritoch 06/06/19
14

Se você ainda não o confirmou, você pode usar apenas

$ git checkout -f

Isso desfará a mesclagem (e tudo o que você fez).

Idealmind
fonte
Tentei isso e, na verdade, aumentou o número de confirmações que minha filial local está à frente.
Barclay
14

Cheguei a essa questão também procurando reverter para corresponder à origem (ou seja, o NO confirma antes da origem). Pesquisando mais, descobrimos que há um resetcomando para exatamente isso:

git reset --hard @{u}

Nota: @{u}é uma abreviação de origin/master. (E, claro, você precisa desse repositório remoto para que isso funcione.)

leanne
fonte
14

Você tem que mudar sua cabeça, não a sua, é claro, mas git HEAD ....

Portanto, antes de responder, vamos adicionar alguns antecedentes, explicando o que é isso HEAD.

First of all what is HEAD?

HEADé simplesmente uma referência ao commit atual (mais recente) no branch atual.
Só pode haver um single HEADa qualquer momento. (excluindo git worktree)

O conteúdo de HEADé armazenado dentro .git/HEADe contém os 40 bytes SHA-1 da confirmação atual.


detached HEAD

Se você não está no último commit, o que significa que HEADestá apontando para um commit anterior no histórico detached HEAD.

insira a descrição da imagem aqui

Na linha de comando, será semelhante a este- SHA-1 em vez do nome do ramo, pois ele HEADnão está apontando para a ponta do ramo atual

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Algumas opções sobre como recuperar de um HEAD desanexado:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Isso fará o checkout do novo ramo apontando para o commit desejado.
Este comando fará checkout para um determinado commit.
Nesse ponto, você pode criar uma ramificação e começar a trabalhar a partir deste ponto.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Você sempre pode usar o reflogtambém.
git reflogexibirá qualquer alteração que tenha atualizado HEADe o check-out da entrada de reflog desejada HEADretornará a esta confirmação.

Sempre que o HEAD for modificado, haverá uma nova entrada no reflog

git reflog
git checkout HEAD@{...}

Isso o levará de volta ao seu commit desejado

insira a descrição da imagem aqui


git reset --hard <commit_id>

"Mova" seu HEAD de volta para o commit desejado.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Nota: ( Desde o Git 2.7 ),
    você também pode usá-lo git rebase --no-autostash.

git revert <sha-1>

"Desfazer" o intervalo de confirmação ou confirmação fornecido.
O comando reset irá "desfazer" quaisquer alterações feitas no commit fornecido.
Um novo commit com o patch de desfazer será confirmado enquanto o commit original também permanecerá no histórico.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Este esquema ilustra qual comando faz o quê.
Como você pode ver lá, reset && checkoutmodifique o arquivo HEAD.

insira a descrição da imagem aqui

CodeWizard
fonte
Este é o tesouro 🐱👤🐱👤🐱👤
Jawand Singh
12

A resposta mais simples é a dada por odinho - Velmont

Primeiro faça git reset --merge ORIG_HEAD

Para aqueles que desejam redefinir depois que as alterações são enviadas, faça o seguinte (porque esta é a primeira postagem vista para qualquer dúvida de fusão do git reset)

git push origin HEAD --force

Isso será redefinido de forma que você não recupere as alterações mescladas novamente após a extração.

Harsha
fonte
10

Apenas para uma opção extra, observei principalmente o modelo de ramificação descrito aqui: http://nvie.com/posts/a-successful-git-branching-model/ e, como tal, tenho me fundido com--no-ff (não avanço rápido) normalmente.

Acabei de ler esta página porque acidentalmente mesclei um ramo de teste em vez do meu ramo de lançamento com o mestre para implantação (site, mestre é o que está ativo). O ramo de teste possui outros dois ramos mesclados e totaliza cerca de seis confirmações.

Então, para reverter todo o commit, eu só precisava de um git reset --hard HEAD^e ele reverteu toda a mesclagem. Como as fusões não foram encaminhadas rapidamente, a mesclagem foi um bloco e um passo atrás é "ramificação não mesclada".

Damien Byrne
fonte
10

Você pode usar apenas dois comandos para reverter uma mesclagem ou reiniciar por uma confirmação específica:

  1. git reset --hard commitHash (você deve usar o commit que deseja reiniciar, por exemplo, 44a587491e32eafa1638aca7738)
  2. git push origin HEAD --force (Enviando o novo ramo mestre local para origem / mestre)

Boa sorte e vá em frente!

Matheus Abreu
fonte
10

Isso pode ser feito de várias maneiras.

1) Interromper mesclagem

Se você estiver no meio de uma mesclagem incorreta (feita erroneamente com ramificação incorreta) e quiser evitar a mesclagem, volte para a ramificação mais recente, como abaixo:

git merge --abort

2) Redefina HEAD para filial remota

Se você estiver trabalhando a partir da ramificação de desenvolvimento remoto, poderá redefinir HEAD para a última confirmação na ramificação remota, conforme abaixo:

git reset --hard origin/develop

3) Exclua a ramificação atual e efetue o checkout novamente no repositório remoto

Considerando que você está trabalhando no ramo de desenvolvimento no repositório local, que é sincronizado com o ramo remoto / de desenvolvimento, você pode fazer o seguinte:

git checkout master 
##to delete one branch, you need to be on another branch, otherwise you will fall with the branch :) 

git branch -D develop
git checkout -b develop origin/develop
Amit Kaneria
fonte
que "1) Abort Merge" foi bastante bonito. Voto a favor.
CodeToLife 6/01
1
Seja cuidadoso! git merge --abort "só pode ser executado após a mesclagem resultar em conflitos. git merge --abort interrompe o processo de mesclagem e tenta reconstruir o estado de pré-mesclagem"
Pedro García Medina
8

Se sua mesclagem e as confirmações correspondentes ainda não foram enviadas, você sempre pode alternar para outra ramificação, excluir a original e recriá-la.

Por exemplo, acidentalmente mesclei um ramo de desenvolvimento no mestre e quis desfazer isso. Usando as seguintes etapas:

git checkout develop
git branch -D master
git branch -t master origin/master

Voila! O mestre está no mesmo estágio da origem e seu estado de fusão incorreta é apagado.

Stephan
fonte
1
Nota: Isso não apenas desfaz a mesclagem, mas também quaisquer confirmações locais que foram feitas desde o último envio à origem.
Martijn Heemels 24/10/12
4

Se você deseja uma solução de linha de comando, sugiro apenas seguir a resposta do MBO.

Se você é iniciante, pode gostar da abordagem gráfica:

  1. Começo gitk (na linha de comando, ou clique com o botão direito do mouse no navegador de arquivos, se houver)
  2. Você pode identificar facilmente o commit de mesclagem lá - o primeiro nó da parte superior com dois pais
  3. Siga o link para o primeiro pai / pai esquerdo (aquele em seu ramo atual antes da mesclagem, geralmente vermelho para mim)
  4. Na confirmação selecionada, clique com o botão direito do mouse em "Redefinir ramificação para aqui", escolha a redefinição definitiva lá
ingerir
fonte
4

Estratégia: Crie um novo ramo de onde tudo estava bom.

Fundamentação da petição: reversão de uma mesclagem é difícil. Existem muitas soluções, dependendo de muitos fatores, como se você confirmou ou enviou sua mesclagem ou se houve novas confirmações desde a mesclagem. Além disso, você ainda precisa ter um entendimento relativamente profundo do git para adaptar essas soluções ao seu caso. Se você seguir cegamente algumas instruções, poderá terminar com uma "mesclagem vazia", ​​onde nada será mesclado, e outras tentativas de mesclagem farão com que o Git diga "Já está atualizado".

Solução:

Vamos dizer que você deseja mesclar devem feature-1.

  1. Encontre a revisão que você deseja receber a mesclagem:

    git log --oneline feature-1
    a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undo
    e5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
    
  2. Confira (volte no tempo):

    git checkout e5f6g7h8
    
  3. Crie uma nova ramificação a partir daí e confira:

    git checkout -b feature-1
    

Agora você pode reiniciar sua mesclagem:

  1. Mesclar: git merge dev

  2. Corrija seus conflitos de mesclagem.

  3. Confirmar: git commit

  4. Quando estiver satisfeito com os resultados, exclua o ramo antigo: git branch --delete feature-1

pyb
fonte
2

Basta criar uma nova ramificação e escolher a cereja desejada.

Seu poupador e mais simples, em seguida, redefine descrito em muitas respostas acima

devi
fonte
1
Eu concordo com esta sugestão, especialmente se você não estiver totalmente confortável com os comandos git listados. Isso pode ser mais lento com mais "labuta", mas se não surgir muito e você estiver preocupado em perder seu trabalho, vale a pena o esforço.
Greg
1

Eu acho que você pode fazer git rebase -i [hash] [branch_name] onde [hash]está o hash de identificação, por quanto tempo você quiser retroceder mais um (ou quantos retornos você desejar) e excluir as linhas dos commits no editor que você não deseja mais . Salve o arquivo. Saída. Orar. E deve ser rebobinado. Você pode precisar fazer um git reset --hard, mas deve ser bom neste momento. Você também pode usar isso para extrair commits específicos de uma pilha, se não quiser mantê-los em seu histórico, mas isso pode deixar seu repositório em um estado que provavelmente não deseja.

tychoish
fonte
1

Se você confirmou a mesclagem:

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard
Dorian
fonte
1
  1. Primeiro, verifique se você comprometeu tudo.

  2. Em seguida, redefina seu repositório para o estado de trabalho anterior:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

    ou usando --hard( isso removerá todas as alterações locais, não confirmadas! ):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

    Use o hash que estava lá antes da sua consolidação incorreta.

  3. Verifique quais confirmações você deseja confirmar novamente na parte superior da versão correta anterior:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
  4. Aplique as confirmações corretas na parte superior da versão correta do seu repositório:

    • Usando cherry-pick (as alterações introduzidas por alguns commits existentes)

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • Ou escolhendo cereja o intervalo de confirmações por:

      • Primeiro, verifique as alterações corretas antes de mesclá-las:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        
      • Primeiro, verifique as alterações corretas antes de mesclá-las:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

        onde esse é o intervalo de confirmações corretas que você confirmou (excluindo a fusão incorreta).

kenorb
fonte
1
  1. git stash

  2. git branch -d the_local_branch

  3. git checkout -t <name of remote>

  4. git stash apply

Isso funcionou para mim .. !!

Siva Kumar
fonte
0

Se você perceber que precisa reverter imediatamente após a mesclagem e não fez mais nada após a tentativa de mesclagem, basta emitir este comando: git reset --hard HEAD@{1} .

Essencialmente, sua mesclagem shaestará apontando HEAD@{0}se nada mais foi confirmado após a mesclagem e, portanto HEAD@{1}, será o ponto anterior antes da mesclagem.

Dut A.
fonte
0

A mais simples das chances mais simples, muito mais simples do que tudo o que foi dito aqui:

Remova sua filial local (local, não remota) e puxe-a novamente. Dessa forma, você desfará as alterações em sua ramificação principal e qualquer pessoa será afetada pela alteração que não deseja enviar. Comece de novo.

Luis
fonte
0

Nesse caso, você desejará redefinir sua ramificação com git reset --hard <branch_name>. Se você deseja salvar suas alterações antes de redefini-las, crie uma nova ramificação e git checkout <branch_name>.

Você também pode redefinir o estado para um commit específico git reset --hard <commit_id>.

Se as alterações foram enviadas, você pode usar git revert <branch_name>. Certifique-se de verificar como usar o git revert e o git checkout em outros cenários também.

Nesha Zoric
fonte