Comment savoir si une branche a déjà été fusionnée en master?

1140

J'ai un référentiel git avec plusieurs branches.

Comment savoir quelles branches sont déjà fusionnées dans la branche principale?

hectorsq
la source

Réponses:

1793

git branch --merged masterrépertorie les branches fusionnées en maître

git branch --mergedrépertorie les branches fusionnées dans HEAD (c'est-à-dire la pointe de la branche actuelle)

git branch --no-merged répertorie les branches qui n'ont pas été fusionnées

Par défaut, cela s'applique uniquement aux succursales locales. Le -adrapeau affichera les branches locales et distantes, et le -rdrapeau ne montrera que les branches distantes.

hectorsq
la source
2
Juste une note latérale, lorsque j'ai essayé de voir si une branche distante avait été fusionnée, j'ai d'abord configuré une branche de suivi locale, identifié l'état avec git branch --mergedpuis supprimé les branches locales et distantes.
Kenneth Kalmer du
83
Apparemment, git branch -a --merged/no-mergedcela fonctionne également, sans créer de branche de suivi locale dans le processus.
fresskoma
70
Ou tout simplement git branch -r --merged/--no-mergedpour ne trouver que des succursales distantes.
Asfand Qazi
5
Est-il possible de supprimer les branches non fusionnées qui ont été fusionnées après le rebasage?
Ashfame
9
Notez que --merged/--no-mergedprend un argument de validation facultatif après. Au moins dans ma version de git (1.9.1), l'ajout du drapeau -aou -raprès cela me donne une erreur fatale. Ajoutez le -aou -r avant --(no-)merged .
Jonathan Gawrych
113

Vous pouvez utiliser la git merge-basecommande pour trouver le dernier commit commun entre les deux branches. Si ce commit est le même que votre chef de branche, alors la branche a été complètement fusionnée.

Notez que git branch -dcela fait déjà ce genre de choses car il refusera de supprimer une branche qui n'a pas encore été complètement fusionnée.

Greg Hewgill
la source
3
La réponse de @ hari explique plus en détail comment l'utiliser.
Muhd
comment pouvons-nous le faire automatiquement / par programme?
Alexander Mills
1
"n'a pas déjà été complètement fusionné" ... complètement fusionné dans quelle branche?
Alexander Mills
@AlexanderMills: dans votre branche actuelle.
Greg Hewgill
2
@AlexanderMills: git branch -drefusera de supprimer une branche qui n'a pas été fusionnée dans la branche actuelle. Ne pas supprimer la branche actuelle .
Greg Hewgill
27

Il existe également une solution d'interface graphique. Tapez simplement

gitk --all

Une nouvelle fenêtre d'application vous demandera une représentation graphique de l'ensemble de votre référentiel, où il est très facile de savoir si une branche a déjà été fusionnée ou non

iberbeu
la source
17
Ce qui, pour être clair, nécessite l'installation d'une application qui ne fait pas partie du gitclient. Sur Ubuntu, apt-get install gitk.
metame
Sur macOS, si vous avez installé Homebrew, ce serait brew install git-gui, pour accéder gitkà la ligne de commande.
program247365
24

J'utilise la fonction bash suivante comme: git-is-merged develop feature/new-feature

git-is-merged () {
  merge_destination_branch=$1
  merge_source_branch=$2

  merge_base=$(git merge-base $merge_destination_branch $merge_source_branch)
  merge_source_current_commit=$(git rev-parse $merge_source_branch)
  if [[ $merge_base = $merge_source_current_commit ]]
  then
    echo $merge_source_branch is merged into $merge_destination_branch
    return 0
  else
    echo $merge_source_branch is not merged into $merge_destination_branch
    return 1
  fi
}
Carl G
la source
3
cela ne fonctionne pas. Si la branche source a déjà été fusionnée dans la branche de destination, puis que la branche de destination obtient quelques commits de plus, cela ne fonctionne plus, mais je ne sais pas pourquoi
Alexander Mills
1
voir la question ici: stackoverflow.com/questions/51355331/…
Alexander Mills
18

Utilisez git merge-base <commit> <commit>.

Cette commande trouve les meilleurs ancêtres communs entre deux commits. Et si l'ancêtre commun est identique au dernier commit d'une "branche", alors nous pouvons sans risque supposer qu'une "branche" a déjà été fusionnée dans le maître.

Voici les étapes

  1. Trouver le dernier hachage de validation sur la branche principale
  2. Trouver le dernier hachage de validation sur une "branche"
  3. Exécuter la commande git merge-base <commit-hash-step1> <commit-hash-step2>.
  4. Si la sortie de l'étape 3 est identique à la sortie de l'étape 2, alors une "branche" a déjà été fusionnée en maître.

Plus d'informations sur git merge-base https://git-scm.com/docs/git-merge-base .

Hari
la source
2
Je pense que cela ne vous dira que si les conseils sont fusionnés. Par exemple, cela ne vous dira pas si a masterété fusionné branch, puis 4 commits supplémentaires ont été ajoutés branch.
mkobit
Pourquoi pas git log -1 $(git merge-base base-branch feature-branch)et si vous voyez feature-branchdans la sortie, alors vous savez qu'ils sont fusionnés?
Carl G
12

Sur le thème du nettoyage des succursales distantes

git branch -r | xargs -t -n 1 git branch -r --contains

Ceci répertorie chaque branche distante suivie par les branches distantes dans lesquelles se trouvent leurs derniers SHA.

Ceci est utile pour discerner quelles branches distantes ont été fusionnées mais pas supprimées, et lesquelles n'ont pas été fusionnées et sont donc en décomposition.

Si vous utilisez 'tig' (c'est comme gitk mais basé sur un terminal), vous pouvez

tig origin/feature/someones-decaying-feature

pour voir l'historique des validations d'une branche sans avoir à passer à la caisse

xxjjnn
la source
3
Bravo cet homme! Très utile une fois que vous avez compris ce qu'il affiche réellement! L'application GitHub doit l'intégrer dans un affichage visuel de vos branches, plutôt que dans une liste alphabétique sans hiérarchie!
CMash
12

Afin de vérifier quelles branches sont fusionnées en master, vous devez utiliser ces commandes:

  • git branch <flag[-r/-a/none]> --merged master liste de toutes les branches fusionnées en master.
  • git branch <flag[-r/-a/none]> --merged master | wc -l compter le nombre de toutes les branches fusionnées en maître.

Les drapeaux sont:

  • -adrapeau - (tous) montrant les succursales éloignées et locales
  • -rdrapeau - (distant) affichant uniquement les branches distantes
  • <emptyFlag>- montrant uniquement les succursales locales

par exemple: git branch -r --merged master vous montrera tous les référentiels distants fusionnés dans master.

avivamg
la source
5

Voici mes techniques lorsque j'ai besoin de déterminer si une branche a été fusionnée, même si elle a peut-être été rebasée pour être à jour avec notre branche principale, ce qui est un scénario courant pour les branches de fonctionnalités.

Aucune de ces approches n'est infaillible, mais je les ai trouvées utiles à plusieurs reprises.

1 Afficher le journal pour toutes les branches

En utilisant un outil visuel comme gitk ou TortoiseGit, ou simplement git log avec --all, parcourez l'historique pour voir toutes les fusions vers la branche principale. Vous devriez pouvoir repérer si cette branche de fonctionnalité particulière a été fusionnée ou non.

2 Toujours supprimer la branche distante lors de la fusion dans une branche de fonction

Si vous avez l'habitude de toujours supprimer la branche locale et la branche distante lorsque vous fusionnez dans une branche de fonctionnalité, vous pouvez simplement mettre à jour et tailler les télécommandes sur votre autre ordinateur et les branches de fonctionnalité disparaîtront.

Pour ne pas oublier de le faire, j'utilise déjà des extensions de flux git (édition AVH) pour créer et fusionner mes branches de fonctionnalités localement, j'ai donc ajouté le hook de flux git suivant pour me demander si je souhaite également supprimer automatiquement la branche distante.

Exemple de branche de fonction de création / finition

554 Andreas:MyRepo(develop)$ git flow start tmp
Switched to a new branch 'feature/tmp'

Summary of actions:
- A new branch 'feature/tmp' was created, based on 'develop'
- You are now on branch 'feature/tmp'

Now, start committing on your feature. When done, use:

     git flow feature finish tmp

555 Andreas:MyRepo(feature/tmp)$ git flow finish
Switched to branch 'develop'
Your branch is up-to-date with 'if/develop'.
Already up-to-date.

[post-flow-feature-finish] Delete remote branch? (Y/n)
Deleting remote branch: origin/feature/tmp.

Deleted branch feature/tmp (was 02a3356).

Summary of actions:
- The feature branch 'feature/tmp' was merged into 'develop'
- Feature branch 'feature/tmp' has been locally deleted
- You are now on branch 'develop'

556 Andreas:ScDesktop (develop)$

.git / hooks / post-flow-feature-finish

NAME=$1
ORIGIN=$2
BRANCH=$3

# Delete remote branch
# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty

while true; do
  read -p "[post-flow-feature-finish] Delete remote branch? (Y/n) " yn
  if [ "$yn" = "" ]; then
    yn='Y'    
  fi
  case $yn in
      [Yy] ) 
        echo -e "\e[31mDeleting remote branch: $2/$3.\e[0m" || exit "$?"
        git push $2 :$3; 
        break;;
      [Nn] ) 
        echo -e "\e[32mKeeping remote branch.\e[0m" || exit "$?"
        break;;
      * ) echo "Please answer y or n for yes or no.";;
  esac
done

# Stop reading user input (close STDIN)
exec <&-
exit 0

3 Recherche par message de validation

Si vous ne supprimez pas toujours la branche distante, vous pouvez toujours rechercher des validations similaires pour déterminer si la branche a été fusionnée ou non. Le piège ici est que la branche distante a été redéfinie sur le non reconnaissable, comme écraser les commits ou changer les messages de commit.

  • Récupérer et tailler toutes les télécommandes
  • Rechercher le message du dernier commit sur la branche de fonctionnalité
  • Voir si une validation avec le même message peut être trouvée sur la branche principale

Exemples de commandes sur la branche principale:

gru                   
gls origin/feature/foo
glf "my message"

Dans ma configuration bash .profile

alias gru='git remote update -p'
alias glf=findCommitByMessage

findCommitByMessage() {
    git log -i --grep="$1"
}
angularsen
la source
@anjdeas - étape 1 - comment savoir quelles branches ont été fusionnées en main. J'ai regardé les journaux et les outils de l'interface graphique - et je ne trouve nulle part où cela montre explicitement cela ???
The Huff
@TheHuff Essayez ceci:git log --all --color --graph --decorate --topo-order --date=relative --abbrev-commit --pretty=format:"%C(green)%h %C(red bold)[%<(14)%ad] %Creset%s%Cred%d%C(blue) [%an]"
angularsen
@TheHuff Dans TortoiseGit, si vous êtes sur la branche principale, il devrait afficher toutes les fusions dans main.
angularsen
Merci - mais comment savoir ce qu'est une fusion? Je suppose que ce sont tous des commits - est-ce vrai?
The Huff
@TheHuff: Vous devriez voir visuellement deux flux / chemins de validations fusionner ensemble en une seule validation "en aval" (plus haut dans la vue journal). Ce commit est un commit de fusion. De plus, git logvous pouvez ajouter --mergespour afficher uniquement les validations de fusion. stackoverflow.com/a/25986615/134761
angularsen
4

Voici un petit one-liner qui vous permettra de savoir si votre branche actuelle incorpore ou est à court de données d'une branche d'origine / maître distante:

$ git fetch && git branch -r --merged | grep -q origin/master && echo Incorporates origin/master || echo Out of date from origin/master

Je suis tombé sur cette question lorsque je travaillais sur une branche de fonctionnalité et que je voulais souvent m'assurer que le travail le plus récent était intégré dans ma propre branche de travail distincte.

Pour généraliser ce test, j'ai ajouté l'alias suivant à mon ~ / .gitconfig:

[alias]
   current = !git branch -r --merged | grep -q $1 && echo Incorporates $1 || echo Out of date from $1 && :

Ensuite, je peux appeler:

$ git current origin/master

pour vérifier si je suis à jour.

radke
la source