Reverter uma mesclagem Git

225
develop branch
--> dashboard (working branch)

Eu uso git merge --no-ff developpara mesclar todas as alterações upstream no painel

log do git:

commit 88113a64a21bf8a51409ee2a1321442fd08db705
Merge: 981bc20 888a557
Author: XXXX <>
Date:   Mon Jul 30 08:16:46 2012 -0500

    Merge branch 'develop' into dashboard

commit 888a5572428a372f15a52106b8d74ff910493f01
Author: root <[email protected]>
Date:   Sun Jul 29 10:49:21 2012 -0500

    fixed end date edit display to have leading 0

commit 167ad941726c876349bfa445873bdcd475eb8cd8
Author: XXXX <>
Date:   Sun Jul 29 09:13:24 2012 -0500

A mesclagem tinha mais de 50 confirmações nela, e eu estou querendo saber como reverter a mesclagem para que o painel volte para a pré-mesclagem de estado

A segunda parte disso é que, se eu não me fundir --no-ff, não recebo o commit ' Merge branch' develop 'into dashboard ' .. Como eu reverteria essa mesclagem?

cgmckeever
fonte
3
Possível duplicata de desfazer uma mesclagem do Git? .

Respostas:

320

A reversão de uma consolidação de mesclagem foi exaustivamente abordada em outras perguntas. Quando você faz uma mesclagem de avanço rápido, a segunda que você descreve, pode usar git resetpara voltar ao estado anterior:

git reset --hard <commit_before_merge>

Você pode encontrar o <commit_before_merge>com git reflog, git logou, se você estiver sentindo o moxy (e ter o resto não fez nada):git reset --hard HEAD@{1}

Christopher
fonte
6
obrigado pela resposta rápida. olhando para o log do git, o commit antes da mesclagem é 50+ confirmado, pois o git merge develop realmente coloca todos os outros commits. Eu acho que o que eu não entendo é, se eu não sei o que / onde foi essa mesclagem - como a encontro? Você mencionou encontrar o commit_before_merge .. Acho que não estou entendendo essa parte
Cgmckeever 30/07/12
4
parece que com o git reflog parece resumir bem as últimas cabeças e me permite saber para onde preciso redefinir. O log do git parece ter muita granularidade para identificar o local para o qual redefinir. Obrigado
cgmckeever
1
Sim, reflogé um salva-vidas. HEAD@{1}descreve apenas o segundo estado mais recente de HEAD, ou mais tecnicamente: "Uma ref seguida pelo sufixo @ com uma especificação ordinal incluída em um par de chaves (por exemplo, {1}, {15}) especifica o n-ésimo valor anterior desse valor ref. "
30712 Christopher
4
Que tal empurrar a reversão para controle remoto? Não vejo como isso funcionará.
Anton Savelyev
2
Isso é inútil. Destrói todas as confirmações após a mesclagem.
aaa90210 22/07/19
151

Daqui:

http://www.christianengvall.se/undo-pushed-merge-git/

git revert -m 1 <merge commit hash>

Git revert adiciona um novo commit que reverte o commit especificado.

O uso de -m 1 indica que isso é uma mesclagem e queremos reverter para o commit pai na ramificação principal. Você usaria -m 2 para especificar o ramo de desenvolvimento.

sturrockad
fonte
30
Observe que você não pode mesclar novamente a ramificação depois disso, pois os documentos dizem: "A reversão de uma consolidação de mesclagem declara que você nunca desejará que as alterações na árvore sejam trazidas pela mesclagem. Como resultado, as mesclagens posteriores somente trarão alterações na árvore introduzidas por confirmações que não são ancestrais da mesclagem revertida anteriormente. Isso pode ou não ser o que você deseja ".
Dalibor Karlović
23
@ DaliborKarlović Essa afirmação é um pouco dura. Definitivamente, você pode recuperar essas alterações mais tarde, o truque é reverter a confirmação de reversão. Mais informações aqui na seção "Revertendo o
reverso
3
Infelizmente, o herelink no comentário @Hilikus não é mais válido. O site afirma que o conteúdo foi movido para um livro ( git-scm.com/book/en/v2 ), mas, nesse caso, não é trivial localizar nele.
Jesse Chisholm
@ DaliborKarlović é este o caso com a resposta acima de @Christopher?
James B
3
O conteúdo fusões desfazer foi transferido para aqui
SEK
28

Apenas redefina o commit de mesclagem com git reset --hard HEAD^.

Se você usar --no-ff, o git sempre cria uma mesclagem, mesmo que você não cometa nada no meio. Sem --no-ff, o git fará um avanço rápido, o que significa que seus ramos HEAD serão definidos como HEAD do ramo mesclado. Para resolver isso, localize o ID do commit que você deseja reverter para e git reset --hard $COMMITID.

Nico Erfurth
fonte
1
Boa solução se você não conhece o commit antes da mesclagem.
precisa
Trabalhou para mim como eu não sei confirmar o ID. + 1
Anant Singh --- Alive to Die
se a mesclagem indesejada já estava confirmada no controle remoto, usei o git push -f para atualizar a ramificação remota após a reversão.
zumek 5/06
16
git revert -m 1 88113a64a21bf8a51409ee2a1321442fd08db705

Mas pode ter efeitos colaterais inesperados. Veja a --mainline parent-numberopção em git-scm.com/docs/git-revert

Talvez uma maneira bruta, mas eficaz, seja verificar o pai esquerdo desse commit, fazer uma cópia de todos os arquivos, fazer checkout HEADnovamente e substituir todo o conteúdo pelos arquivos antigos. Então o git dirá o que está sendo revertido e você criará seu próprio reverter commit :)!

Jorge Orpinel
fonte
1
+1 porque esta resposta não interfere no histórico da mesma forma que a redefinição (realmente importante se você já tiver enviado para o controle remoto). Mas que efeitos colaterais inesperados devo esperar?
Pedromanoel
3
Esse é o efeito colateral que você mencionou? Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.
Pedromanoel
1
Você diz que git reseté a solução, mas também menciona que pode ter efeitos colaterais inesperados. No entanto, essa ligação é de git revert, não git reset:)
Mark
2
Observe que o git reset não possui um sinalizador -m. Observe também que @JorgeOrpinel faz referência aos documentos do git-revert, não ao git-reset. Eu acho que ele quis dizer git revertnãogit reset
Devin Gleason Lambert
Como evitar Mainline foi especificado, mas commit 1234xyz não é um erro de mesclagem .
Achal 17/01
0

Se você mesclou a ramificação, reverteu a mesclagem usando uma solicitação pull e mesclou essa solicitação pull para reverter.

A maneira mais fácil que senti foi:

  1. Retire uma nova ramificação do develop / master (onde você mesclou)
  2. Reverter a "reverter" usando git revert -m 1 xxxxxx(se a reversão foi mesclada usando uma ramificação) ou usando git revert xxxxxxse fosse uma reversão simples
  3. O novo ramo agora deve ter as alterações que você deseja mesclar novamente.
  4. Faça alterações ou mescle esse ramo para desenvolver / dominar
Rohin Tak
fonte