web-dev-qa-db-fra.com

Git et "La branche 'x' n'est pas complètement fusionnée" Erreur

Voici les commandes que j'ai utilisées depuis la branche master

git branch experiment
git checkout experiment

Ensuite, j'ai apporté des modifications à mes fichiers, les ai validées et j'ai transféré la nouvelle branche vers GitHub.

git commit .
git Push -u Origin experiment

Notez qu'après git commit . on m'a demandé un message de validation et je lui en ai donné un. Plus tard, j'ai décidé de fusionner ma branche d'expérimentation dans la branche principale.

git checkout master
git merge experiment

Enfin, j'ai poussé les modifications vers GitHub.

git Push -u Origin master

Tout s’est bien passé jusqu’à ce que j’essaie de supprimer ma branche d’expérience avec

git branch -d experiment

J'ai reçu le message d'erreur error: The branch 'experiment' is not fully merged. je suis un peu nouveau à git, et je ne sais pas combien de plus je pourrais fusionner les deux branches. Qu'est-ce que j'oublie ici?

261
mellowsoon

Note La formulation a été modifiée en réponse aux commentaires. Merci @slekse
 Ce n'est pas une erreur, c'est un avertissement. Cela signifie que la branche que vous êtes sur le point de supprimer contient des validations inaccessibles depuis: sa branche en amont ou HEAD (révision actuellement extraite). En d'autres termes, quand vous pourriez perdre des validations¹.

En pratique, cela signifie que vous avez probablement modifié, modifié ou filtré les commits et qu'ils ne ne semblent pas identiques.

Par conséquent, vous pouvez éviter l'avertissement en vérifiant une branche contenant les commits qui vous intéressent un- référence en supprimant cette autre branche.²

Vous voudrez vérifier que vous ne manquez en réalité aucun commit vital:

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

Cela vous donnera une liste de tous les non-partagés entre les branches. Si vous êtes curieux, il pourrait y avoir une différence sans --cherry-pick et cette différence pourrait bien être la raison de l'avertissement que vous recevez:

--cherry-pick

Omettez toute validation qui introduit le même changement qu'une autre validation de "l'autre côté" lorsque l'ensemble des validations est limité avec une différence symétrique. Par exemple, si vous avez deux branches, A et B, la méthode habituelle pour répertorier tous les commits d'un seul côté est avec --left-right, comme dans l'exemple ci-dessus dans la description de cette option. Il montre cependant les commits qui ont été choisis par la cerise de l'autre branche (par exemple, "3ème sur b" peut être choisi par la branche A). Avec cette option, ces paires de commits sont exclues de la sortie.


¹ Ils ne sont vraiment que des ordures collectées après un certain temps, par défaut. De plus, la commande git-branch ne vérifie pas l'arborescence de révision de de toutes les branches . L'avertissement est là pour éviter les erreurs évidentes.

² (Ma préférence ici est simplement de forcer la suppression, mais vous voudrez peut-être avoir l’assurance supplémentaire).

282
sehe

Comme Drew Taylor l'a souligné, la suppression de branche avec -d considère uniquement le actuel HEAD pour déterminer si la branche est "totalement fusionnée". Il se plaindra même si la branche is a fusionné avec une autre branche. Le message d'erreur pourrait certainement être plus clair à cet égard ... Vous pouvez soit extraire la branche fusionnée avant de la supprimer, soit simplement utiliser git branch -D. Le D majuscule annulera entièrement le chèque.

77
drwowe

J'ai essayé la réponse de Sehe et cela n'a pas fonctionné.

Pour trouver les commits qui n'ont pas été fusionnés, utilisez simplement:

git log feature-branch ^master --no-merges
13
qwertzguy

C'est ce qui m'est arrivé aujourd'hui, alors que je fusionnais ma toute première branche de long métrage dans master. Comme certains l'ont dit dans un fil sur SO, le truc était de revenir en mode maître avant d'essayer de supprimer la branche. Une fois dans le maître, git était heureux de supprimer la branche sans aucun avertissement.

13
Drew Taylor

Git vous avertit que vous pourriez perdre votre historique en supprimant cette branche. Même si elle ne supprime pas immédiatement les commits, tout ou partie des commits de la branche deviendrait inaccessible s'ils ne faisaient pas partie d'une autre branche également.

Pour que la branche experiment soit "entièrement fusionnée" dans une autre branche, son commit de pointe doit être un ancêtre de la pointe de l’autre branche, ce qui fait que les commits de experiment constituent un sous-ensemble de l’autre branche. Cela rend sûre de supprimer experiment, car tous ses commits resteront dans l’historique du référentiel via l’autre branche. Il doit être "entièrement" fusionné, car il a peut-être déjà été fusionné plusieurs fois, mais des commits ont maintenant été ajoutés depuis la dernière fusion et ne sont pas contenus dans l'autre branche.

Cependant, Git ne vérifie pas toutes les autres branches du référentiel. seulement deux:

  1. La branche actuelle (HEAD)
  2. La branche amont, s'il en existe une

La "branche en amont" pour experiment, comme dans votre cas, est probablement Origin/experiment. Si experiment est entièrement fusionné dans la branche actuelle, Git le supprime sans réclamation. Si ce n'est pas le cas, mais qu'il est complètement fusionné dans sa branche en amont, alors Git lance un avertissement ressemblant à ceci:

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

xxxxxxxx indique un identifiant de validation. Une fusion complète dans son amont indique que les commits dans experiment ont été placés dans le référentiel Origin. Ainsi, même si vous les perdez ici, ils peuvent au moins être sauvegardés ailleurs.

Comme Git ne vérifie pas les autres branches, il peut être sûr de supprimer une branche car vous savez qu’elle est complètement fusionnée dans une autre. vous pouvez le faire avec l'option -D comme indiqué, ou basculez d'abord sur cette branche et laissez Git confirmer le statut totalement fusionné pour vous.

4
troore

pour voir les changements qui ne sont pas fusionnés, j'ai fait ceci:

git checkout experiment
git merge --no-commit master

git diff --cached

Note: Ceci montre les changements dans master qui ne sont pas dans experiment.

N'oubliez pas de:

git merge --abort

Quand tu as fini, regarde.

3
ThorSummoner

Solution la plus simple avec Explication (solution vérifiée) (= fait face au problème auparavant)

Le problème est:

1- Je ne peux pas supprimer une branche

2- Le terminal continue d’afficher un message d’avertissement indiquant que certains validations ne sont pas encore approuvées.

3- sachant que j'ai vérifié le maître et la branche et qu'ils sont identiques (à jour)

solution:

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

Explication:

lorsque votre branche est connectée à une branche distante en amont (sur Github, Bitbucket ou autre), vous devez la fusionner (Push) dans le maître et vous devez Transférer les nouvelles modifications (commits) vers le référentiel distant (Github, Bitbucket ou quelle que soit) de la branche,

ce que j'ai fait dans mon code, c'est que je suis passé à master, puis à fusionner la branche dans celui-ci (pour m'assurer qu'ils sont identiques sur votre ordinateur local), puis j'ai à nouveau basculé vers la branche et transféré les mises à jour ou les modifications dans la ligne distante. repo en utilisant "git Push".

après cela, je suis de nouveau passé au maître et j'ai essayé de supprimer la branche. Le problème (message d'avertissement) a disparu et la branche a été supprimée avec succès.

2
Elta3lab

Vous pouvez simplement comprendre:

git log --cherry master ... expérimental

L'option --cherry est un synonyme de --right-only --cherry-mark --no-merges

la page de manuel de git-log dit

il est utile de limiter la sortie aux commits de notre côté et de marquer ceux qui ont été appliqués de l’autre côté d’une histoire fourchue avec git log --cherry en amont ... mybranch, similaire à git cherry en amont de mybranch.

FYI. --cherry-pick omet les validations équivalentes mais --cherry-marks ne le fait pas. Il est utile de rechercher des modifications de base et de forcer les modifications mises à jour entre la branche publique en amont et la branche publique co-active

2
yongbin

Je n'avais pas la branche en amont sur mon git local. J'avais créé une branche locale à partir de master, git checkout -b mybranch. J'ai créé une branche avec une interface graphique bitbucket sur le git en amont et poussé ma branche locale (mybranch) vers cette branche en amont. Une fois que j'ai fait un git sur mon git local pour récupérer la branche en amont, je pouvais faire une branche git - d mon branche.

1
edW