Git e "O ramo 'x' não está totalmente mesclado" Erro

294

Aqui estão os comandos que usei no ramo principal

git branch experiment
git checkout experiment

Depois, fiz algumas alterações nos meus arquivos, confirmei as alterações e enviei a nova ramificação para o GitHub.

git commit . -m 'changed files'
git push -u origin experiment

Mais tarde, decidi mesclar meu ramo de experimento no ramo mestre.

git checkout master
git merge experiment

Finalmente, enviei as alterações para o GitHub.

git push -u origin master

Tudo correu bem até que eu tentei excluir minha ramificação do experimento usando

git branch -d experiment

Recebi a mensagem de erro error: The branch 'experiment' is not fully merged.: sou um pouco novo em git e não sei quanto mais poderia mesclar os dois ramos. O que estou perdendo aqui?

mellowsoon
fonte
2
Esta publicação ajuda você? stackoverflow.com/questions/1710894/…
Chrisdigital
2
Isto vem-se, por vezes, quando eu fiz umgit commit --amend
Arcolye
12
Além disso - lembre-se de que esta mensagem será exibida após a squash: stackoverflow.com/q/41946475/109941 #
Jim G.
Acho que o cenário mais comum é que você só precisa puxar as alterações recém-mescladas antes de excluir o ramo localmente.
RaisinBranCrunch 17/04/19

Respostas:

313

Nota O texto foi alterado em resposta aos comentários. Obrigado @slekse
Isso não é um erro, é um aviso. Isso significa que o ramo que você está prestes a excluir contém confirmações que não são acessíveis a partir de nenhum dos seguintes: seu ramo upstream ou HEAD (revisão com check-out atualmente). Em outras palavras, quando você pode perder commits¹.

Na prática, isso significa que você provavelmente alterou, reformulou ou filtrou confirmações e elas não parecem idênticas.

Portanto, você pode evitar o aviso consultando uma ramificação que contém as confirmações sobre as quais você não faz referência excluindo a outra ramificação.²

Você deseja verificar se na verdade não está perdendo nenhum commit vital:

git log --graph --left-right --cherry-pick --oneline master...experiment

Isso fornecerá uma lista de todos os não compartilhados entre os ramos. Caso você esteja curioso, pode haver uma diferença sem --cherry-picke essa diferença pode ser a razão do aviso que você recebe:

--cherry-pick

Omita qualquer confirmação que introduza a mesma alteração que outra confirmação no "outro lado" quando o conjunto de confirmações estiver limitado pela diferença simétrica. Por exemplo, se você tiver duas ramificações, A e B, uma maneira usual de listar todas as confirmações em apenas um lado delas é com - esquerda-direita, como no exemplo acima na descrição dessa opção. No entanto, mostra os commits que foram escolhidos cereja do outro ramo (por exemplo, "3rd on b" pode ser escolhido cereja do ramo A). Com esta opção, esses pares de confirmações são excluídos da saída.


¹ são realmente apenas lixo coletado depois de um tempo, por padrão. Além disso, o git-branchcomando não verifica a árvore de revisão de todas as ramificações . O aviso existe para evitar erros óbvios.

² (Minha preferência aqui é forçar apenas a exclusão, mas você pode ter a garantia extra).

ver
fonte
24
Obrigado. A frase-chave era "contém confirmações que não são acessíveis a partir de nenhum outro cabeçalho de referência". Mesmo que eu não precisasse mais do ramo do experimento, e já o tivesse mesclado no mestre, e planejasse excluí-lo da origem, o git não ficaria feliz até que eu levasse as alterações do experimento para a origem. Acho que esse aviso foi uma espécie de verificação de sanidade.
precisa saber é o seguinte
35
-1 "Significa que o ramo que você está prestes a excluir contém confirmações que não são acessíveis a partir de nenhum outro cabeçalho de referência." Isso não está correto. O aviso significa que a ramificação não pode ser acessada nem a montante (se houver), nem a HEAD atual. Veja a página de manual do git-branch.
Sleske
3
@TachyonVortex Nice link. O comando git branch -vv realmente esclareceu o que estava acontecendo comigo.
Jason Massey
11
@sleske Obrigado pelo comentário - esta resposta realmente deve ser editada. É uma pena que tenha sido altamente votado porque a principal frase explicativa está incorreta. Acabei de ter esse problema e passei um tempo irritantemente longo tentando descobrir qual era o problema, e apenas o ramo de rastreamento remoto havia sido excluído como parte da solicitação de recebimento e, desde que recebi as alterações do mestre na filial local. O único 'problema' não foi encontrar a ramificação de rastreamento remoto, que foi excluída (e eu estava tentando excluir a ramificação local pelo mesmo motivo).
Ely
3
Sim, isso pode acontecer apenas ao tentar excluir um ramo local se você estiver em um ramo diferente daquele em que você o criou quando o criou. "Commits que não são acessíveis a partir de qualquer outro árbitro" é incorreto e desnecessariamente assustador!
Amalgovinus
80

Como Drew Taylor apontou, a exclusão da ramificação com -d considera apenas o HEAD atual para determinar se a ramificação está "totalmente mesclada". Ele reclamará mesmo que o ramo seja mesclado com outro ramo. A mensagem de erro pode definitivamente ser mais clara a esse respeito ... Você pode fazer o checkout do ramo mesclado antes de excluir ou simplesmente usar o git branch -D. O capital -D substituirá inteiramente o cheque.

drwowe
fonte
2
A parte sobre o HEAD atual o corrigiu para mim. Meu mestre era diferente do ramo de funcionalidade de que eu criei o conflito ramo: D
viki.omega9
1
Para alguém aprendendo git, a palavra "atual" parece redundante com "HEAD"? Não existe um HEAD não recorrente - o HEAD, por definição, é o ramo atual . Estou esquecendo de algo? Suponho que você possa dizer "ramo atual" ou "CABEÇA", mas não "CABEÇA atual".
precisa saber é o seguinte
Existe alguma maneira de alterar / configurar isso (por exemplo, sempre checar origin/master?) Acho que o check-out origin/masterprimeiro não é muito oneroso, mas parece um fluxo estranho - por que preciso verificar origin/masterlocalmente só para você verificar se minhas alterações foram mescladas aí?
Alec
15

Eu tentei a resposta de ela e não funcionou.

Para encontrar os commits que não foram mesclados, basta usar:

git log feature-branch ^master --no-merges
qwertzguy
fonte
14

Isso aconteceu comigo hoje, quando eu estava mesclando meu primeiro ramo de recursos novamente no master. Como alguns disseram em um tópico em outro lugar no SO, o truque foi voltar ao mestre antes de tentar excluir o ramo. De volta ao master, o git ficou feliz em excluir o ramo sem nenhum aviso.

Drew Taylor
fonte
7
Não parece que esse é o problema específico aqui, mas encontrei o problema que você descreve agora, então obrigado!
Daniel Buckmaster
4

O Git está avisando que você pode perder o histórico excluindo este ramo. Mesmo que na verdade não exclua nenhuma confirmação imediatamente, algumas ou todas as confirmações na ramificação se tornarão inacessíveis se elas também não fizerem parte de outra ramificação.

Para que a ramificação experimentseja "totalmente mesclada" em outra ramificação, seu commit de dica deve ser um ancestral da dica do outro branch, fazendo com que o commit seja feito em experimentum subconjunto do outro branch. Isso torna seguro excluir experiment, pois todas as confirmações permanecerão parte do histórico do repositório por meio de outra ramificação. Ele deve ser mesclado "totalmente", porque já pode ter sido mesclado várias vezes, mas agora foram adicionados commit desde a última mesclagem que não está contida no outro ramo.

O Git não verifica todos os outros ramos do repositório; só dois:

  1. O ramo atual (HEAD)
  2. O ramo upstream, se houver um

O "ramo upstream" para experiment, como no seu caso, é provavelmente origin/experiment. Se experimentfor totalmente mesclado no ramo atual, o Git o excluirá sem reclamação. Se não estiver, mas estiver totalmente mesclado em sua ramificação upstream, o Git continuará com um aviso parecido com:

warning: deleting branch 'experiment' that has been merged
to 'refs/remotes/origin/experiment', but not yet merged to
HEAD.
Deleted branch experiment (was xxxxxxxx).

Onde xxxxxxxxindica um ID de confirmação. Ser totalmente mesclado no upstream indica que as confirmações experimentforam enviadas para o repositório de origem, para que, mesmo que você as perca aqui, elas possam pelo menos ser salvas em outro lugar.

Como o Git não verifica outros ramos, pode ser seguro excluir um ramo porque você sabe que ele está totalmente mesclado em outro; você pode fazer isso com a -Dopção indicada, ou alternar para esse ramo primeiro e deixar o Git confirmar o status totalmente mesclado para você.

Troore
fonte
1
A chave é "totalmente mesclada na ramificação atual ". Eu tinha um ramo X 'do X totalmente mesclado novamente no X e já havia excluído a origem / X'. Mas com o check-out de Y, recebi esse aviso. Quando eu fiz check-out, XI foi capaz de excluir X '. É um tanto estúpido, eu acho.
Lawrence Dol
2
Esta resposta é plagiada a partir daqui sem atribuição chimera.labs.oreilly.com/books/1230000000561/…
Mark Lakata
3

para ver alterações que não são mescladas, fiz o seguinte:

git checkout experiment
git merge --no-commit master

git diff --cached

Nota: Isso mostra alterações nas masterquais não estão experiment.

Não esqueça de:

git merge --abort

Quando você terminar de olhar.

ThorSummoner
fonte
@IgorGanapolsky Dunno exatamente, embora normalmente man git-resete os comandos git reset sejam suficientes para se recuperar de problemas de estado.
ThorSummoner
3

Solução mais fácil com explicação (solução verificada duas vezes) (enfrentou o problema antes)

O problema é:

1- Não consigo excluir um ramo

2- O terminal continua exibindo uma mensagem de aviso de que existem algumas confirmações ainda não aprovadas

3- sabendo que verifiquei o master e o branch e eles são idênticos (atualizados)

solução:

git checkout master
git merge branch_name
git checkout branch_name
git push
git checkout master
git branch -d branch_name

Explicação:

quando sua ramificação estiver conectada à ramificação remota upstream (no Github, bitbucket ou qualquer outra coisa), você precisará mesclá-la (push) no master e enviar as novas alterações (confirmações) ao repositório remoto (Github, bitbucket ou seja qual for) do ramo,

o que fiz no meu código é que mudei para mestre e, em seguida, mesclei a ramificação (para garantir que sejam idênticas na sua máquina local), depois mudei para a ramificação novamente e coloquei as atualizações ou alterações no controle remoto on-line repo usando "git push".

depois disso, mudei para o mestre novamente e tentei excluir a ramificação, o problema (mensagem de aviso) desapareceu e a ramificação foi excluída com êxito

Elta3lab
fonte
3

Você pode simplesmente descobrir:

git log --cherry master ... experimental

--cherry opção é sinônimo de --right-only --cherry-mark --no-merges

A página de manual do git-log disse

é útil limitar a saída aos commits do nosso lado e marcar aqueles que foram aplicados ao outro lado de uma história bifurcada com o git log --cherry upstream ... mybranch, semelhante ao git cherry upstream mybranch.

PARA SUA INFORMAÇÃO. --cherry-pickomite confirmações equivalentes, mas --cherry-marksnão. É útil encontrar uma reformulação e forçar alterações atualizadas entre o ramo público upstream e colaborador

yongbin
fonte
1

Eu não tinha o ramo upstream no meu git local. Eu criei uma filial local a partir do master, git checkout -b mybranch. Criei uma ramificação com a GUI do bitbucket no git upstream e empurrei minha ramificação local (mybranch) para essa ramificação upstream. Depois de fazer uma busca no git no git local para recuperar a ramificação upstream, eu poderia fazer uma ramificação git -d mybranch.

edW
fonte
0

Acredito que a bandeira --forceé o que você realmente está procurando. Basta usar git branch -d --force <branch_name>para excluir o ramo à força.

Sergey Samoylenko
fonte