À l'aide de Git, affichez toutes les validations qui se trouvent dans une branche, mais pas les autres

465

J'ai une ancienne branche que j'aimerais supprimer. Cependant, avant de le faire, je veux vérifier que tous les commits effectués dans cette branche ont à un moment donné été fusionnés dans une autre branche. Ainsi, j'aimerais voir toutes les validations effectuées dans ma branche actuelle qui n'ont été appliquées à aucune autre branche [ou, si cela n'est pas possible sans un script, comment peut-on voir toutes les validations dans une branche qui n'ont pas été appliquées à une autre branche donnée?].

sircolinton
la source
Pour répertorier les commits manquants entre deux branches, vous pouvez utiliser compare-branches.py bitbucket.org/aakef/compare-git-branches
Bernd Schubert
EN RELATION
Ioannis Filippidis

Réponses:

321

Tu veux probablement juste

git branch --contains branch-to-delete

Ceci listera toutes les branches qui contiennent les validations de "branch-to-delete". S'il signale plus que "branche à supprimer", la branche a été fusionnée.

Vos alternatives ne sont vraiment que des choses de syntaxe rev-list. Par exemple, git log one-branch..another-branchmontre tout ce qui one-branchdoit avoir tout another-branch.

Vous pourriez également être intéressé git show-branchpar un moyen de voir où.

Dustin
la source
1
La ligne «Si elle signale quelque chose, la branche a fusionné» peut être mal interprétée: si git branch --contains some-branchseulement elle revient some-branch, alors elle retourne quelque chose, mais elle n'a pas été fusionnée.
Confusion
5
Notez que git log foo..barcela montrera les validations entre la dernière barre et la dernière foo, mais pas d'autres validations manquantes plus loin dans le temps. Pour tout voir en bar mais pas en foo, vous devez utiliser la solution de @ jimmyorr.
Paul A Jungwirth
557

Pour voir la liste des validations sur une branche mais pas sur une autre, utilisez git log:

git log --no-merges oldbranch ^newbranch

... c'est-à-dire afficher les journaux de validation pour toutes les validations sur oldbranch qui ne sont pas sur newbranch. Vous pouvez répertorier plusieurs branches à inclure et à exclure, par exemple

git log  --no-merges oldbranch1 oldbranch2 ^newbranch1 ^newbranch2

Remarque: sous Windows ^est une clé d'échappement, elle doit donc être échappée avec une autre ^:

git log --no-merges oldbranch ^^newbranch
jimmyorr
la source
2
Je l'ai trouvé à la recherche de git compare les commits de deux branches.
Utilisateur
25
Ceci est exactement ce que je cherchais. Mais, l'utilisation ^d'un préfixe ici m'a dérouté. Dans ce contexte, cela signifie exclure cette branche. L'utilisation ^comme suffixe serait une référence relative au commit parent de cette branche.
Joe Flynn
4
merci très utile. Je suis curieux, pourquoi le drapeau --no-merges est-il nécessaire? On veut sûrement voir ces engagements aussi?
Max MacLeod
2
Souhaitez-vous utiliser gitk avec cela? Utilisez simplement gitk oldbranch ^newbranch --no-merges(Testé avec git 1.8.1.1). Note latérale, pour moi, cela ^signifie un engagement HEAD inclusif de la branche newbranch.
Matt
2
@NazariiGudzovatyi - oui, il y a: "-cherry-pick". Il y a énormément d'options pour se connecter sur la page de documentation
romeara
91

Pour afficher les commits dans oldbranch mais pas dans newbranch:

git log newbranch..oldbranch

Pour afficher le diff par ces commits (notez qu'il y a trois points):

git diff newbranch...oldbranch

Voici le doc avec une illustration de schéma https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges

Xuan
la source
Voir le commentaire de Paul A Jungwirth ci-dessus. Il semble que cela va manquer certains vieux commits?
Variable misérable
2
Je ne sais pas ce que signifient les anciens commits. Le double point demande essentiellement à Git de résoudre une gamme de validations qui sont accessibles à partir d'une validation mais ne sont pas accessibles à partir d'une autre. Voici le doc avec une illustration digram git-scm.com/book/en/v2/…
Xuan
1
et si nous sommes sur newbranchou oldbranch, nous pouvons faire git log ..oldbranchou git log newbranch..respectivement
YakovL
La solution de Jimmyorr n'a pas fonctionné pour moi, mais celle-ci l'a fait grâce aux deux points ..entre les noms des arbitres. J'ai également utilisé l' --cherry-pickoption pour masquer les commits qui sont présents sur les deux branches mais qui ont un hachage différent car ils ont été sélectionnés d'une branche à l'autre.
flawyte
58

Pour ceux qui recherchent toujours une réponse simple, consultez git cherry . Il compare les différences réelles au lieu des hachages de validation. Cela signifie qu'il accepte les commits qui ont été sélectionnés ou rebasés.

Vérifiez d'abord la branche que vous souhaitez supprimer:

git checkout [branch-to-delete]

puis utilisez git cherry pour le comparer à votre branche de développement principale:

git cherry -v master

Exemple de sortie:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
- 85867e38712de930864c5edb7856342e1358b2a0 Yet another message

Remarque: L' -vindicateur doit inclure le message de validation avec le hachage SHA.

Les lignes avec le «+» devant sont dans la branche à supprimer, mais pas dans la branche principale. Ceux avec un '-' devant ont un commit équivalent dans master.

Pour JUSTE les commits qui ne sont pas en master, combinez cherry pick avec grep:

git cherry -v master | grep "^\+"

Exemple de sortie:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
Tim S
la source
J'ai essayé cela, mais il indique toujours qu'il y a beaucoup de commits dans le fb (branche de fonctionnalité) qui ne sont pas dans le mb (branche principale). Cependant, si je suis dans le fb et que je fais un git diff mb, je ne vois aucune différence. J'ai utilisé rebase et écrasé tout. Je suis presque certain que c'est pourquoi, mais je veux juste être certain. Si tel est le cas, alors je vais éviter d'écraser si possible; Je suis dans le "camp d'information sans perte". Je me demande s'il serait possible d'ajouter un mode d'affichage du journal qui peut afficher les fusions comme s'il s'agissait de rebases pour garder l'historique propre et pourtant ne perdre aucune information.
Outis Von Nemo
1
Je ne suis pas sûr de votre scénario exact ici, mais si vous avez écrasé plusieurs validations ensemble en une seule et que vous les comparez à une autre branche où les validations sont séparées, cela ne fonctionnera certainement pas. Dans ce cas, vous pouvez simplement utiliser l' diffutilitaire unix pour comparer les différents fichiers. Ou, vous pouvez créer une branche temporaire et écraser toutes les validations similaires à ce que vous avez fait avec la branche d'origine, puis l'utiliser, ce qui, je pense, fonctionnerait.
Tim S
50

Bien que certaines des réponses publiées ici vous aideront à trouver ce que vous cherchez, la sous-commande suivante de git branch est une solution plus adaptée à votre tâche.

--merged est utilisé pour trouver toutes les branches qui peuvent être supprimées en toute sécurité, car ces branches sont entièrement contenues par HEAD.

Alors que dans l' masterun, vous pouvez exécuter la commande pour énumérer les branches que vous pouvez supprimer en toute sécurité, comme suit:

git branch --merged
  develop
  fpg_download_links
* master
  master_merge_static

# Delete local and remote tracking branches you don't want
git branch -d fpg_download_links
git push origin :fpg_download_links
git branch -d master_merge_static
git push origin :master_merge_static

# There is also a flag to specify remote branches in the output
git branch --remotes --merged
Freddie
la source
16

La réponse de jimmyorr ne fonctionne pas sous Windows. il aide à utiliser --notau lieu de ^comme ça:

git log oldbranch --not newbranch --no-merges
sebeck
la source
4
C'est exact, +1. Notez cependant que ^est pris en charge sur Windows, mais il doit être échappé, qui, sous Windows, est ( une autre) ^: git log oldbranch ^^newbranch --no-merges.
VonC
3
Pour être précis, cela fonctionne dans Windows dans la console Powershell, mais nécessite un "^" supplémentaire dans CMD.
Rod
7

S'il s'agit d' une seule (unique) branche que vous devez vérifier, par exemple si vous voulez que la branche 'B' soit complètement fusionnée dans la branche 'A', vous pouvez simplement faire ce qui suit:

$ git checkout A
$ git branch -d B

git branch -d <branchname> a la sécurité que "La branche doit être complètement fusionnée dans HEAD."

Attention : cela supprime en fait la branche B si elle est fusionnée en A.

Jakub Narębski
la source
3

Vous pouvez utiliser ce script simple pour voir les validations qui ne sont pas fusionnées

#!/bin/bash
# Show commits that exists only on branch and not in current
# Usage:
#   git branch-notmerge <branchname>
#
# Setup git alias
#   git config alias.branch-notmerge [path/to/this/script]
grep -Fvf <(git log --pretty=format:'%H - %s') <(git log $1 --pretty=format:'%H - %s')

Vous pouvez également utiliser l'outil git-wtf qui affichera l'état des branches

manRo
la source
0

Utilisez simplement git cherrypour sélectionner tous les commits dans la branche newFeature42par exemple:

git cherry -v master newFeature42

Mꜳltus
la source
-5

Commencez à créer une demande de pull via le service d'hébergement git que vous utilisez. Si la branche a été complètement fusionnée dans la branche de base, vous ne pourrez pas créer le nouveau PR.

Vous n'avez pas besoin de faire la demande d'extraction, utilisez simplement la première étape où vous choisissez des branches.

Par exemple, sur GitHub:

Il n'y a rien à comparer

Impossible de créer un PR pour les succursales qui ont été fusionnées.

Cela n'utilise pas git sur la ligne de commande, mais je trouve souvent qu'il est utile d'utiliser les autres outils à votre disposition avec un modèle mental clair plutôt que d'essayer de se souvenir d'une autre commande git arcanique.

pkamb
la source