2009-11-10 3 views
340

J'ai une vieille branche, que je voudrais supprimer. Cependant, avant de le faire, je veux vérifier que toutes les validations faites à cette branche ont été fusionnées dans une autre branche. Ainsi, j'aimerais voir toutes les validations faites à ma branche actuelle qui n'ont été appliquées à aucune autre branche [ou, si cela n'est pas possible sans script, comment voit-on toutes les validations dans une branche qui n'ont pas été appliquées? à une autre branche donnée?].En utilisant Git, montrer tous les commits qui sont dans une branche, mais pas l'autre (s)

+0

Connexes: https://stackoverflow.com/q/1419623/1959808 –

Répondre

235

Vous probablement voulez

git branch --contains branch-to-delete 

Ceci listera toutes les branches qui contiennent les commits de "branche-to-delete". S'il signale plus que simplement «branchez-supprimer», la branche a été fusionnée.

Vos alternatives sont vraiment des choses de syntaxe rev-list. par exemple. git log one-branch..another-branch montre tout ce que one-branch doit avoir tout another-branch a.

Vous pouvez également être intéressé par git show-branch comme un moyen de voir ce qui est où.

+2

+1. Voir aussi http://stackoverflow.com/questions/850607/difference-in-git-log-origin-master-vs-git-log-origin-master – VonC

+1

La ligne 'Si elle signale quelque chose, la branche a fusionné' peut être mal interprété: si 'git branch --contains some-branch' ne renvoie que' some-branch', alors il retourne quelque chose, mais il n'a * pas * été fusionné. – Confusion

+1

git show-branch est très instructif –

7

Si elle est un (unique) branche que vous devez vérifier, par exemple, si vous voulez que la branche « B » est complètement fusionné dans la branche « A », vous pouvez simplement effectuer les opérations suivantes:

$ git checkout A 
$ git branch -d B 

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

Remarque que cette suppression en fait la branche si elle est fusionnée dans,

+4

* Attention: * 'git branch -d ' efface réellement la branche. Je viens de le faire! – Haywire

414

Pour voir une liste dont commits sont sur une branche, mais pas un autre, utilisez git log:

git log oldbranch ^newbranch --no-merges 

. ..c'est-à-dire, affiche les logs de commit pour tous les commit sur oldbranch qui sont pas sur newbranch. Vous pouvez répertorier plusieurs branches à inclure et à exclure, par ex.

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

Remarque: sous Windows ^ est une clé d'échappement, il doit être échappé avec un autre ^:

git log oldbranch ^^newbranch --no-merges 
+2

Je l'ai trouvé à la recherche de git comparer les commits de deux branches. – User

+16

C'est exactement ce que je cherchais. Mais, en utilisant '^' comme préfixe ici m'a confondu. Dans ce contexte, cela signifie exclure cette branche. L'utilisation de '^' comme suffixe serait une référence relative à la validation parente de cette branche. –

+2

très utile merci. Je suis curieux, pourquoi le drapeau --no-merges est-il nécessaire? Sûrement on veut voir ces commits aussi? –

48

Bien que certaines des réponses affichées ici vous aidera à trouver ce que vous cherchez, ce qui suit sous-commande de git branche est une solution plus adaptée à votre tâche.

--merged is used to find all branches which can be safely deleted, since those branches are fully contained by HEAD.

Alors que dans master on pourrait exécuter la commande d'énumérer les branches on pourrait supprimer en toute sécurité, comme ceci:

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 
+1

Une commande très utile pour le nettoyage. – Kzqai

+0

Commande très utile en effet. La réponse acceptée est plus pertinente à la question, mais je vais certainement utiliser à l'avenir ce que vous avez partagé, alors merci – Cec

3

Vous pouvez utiliser ce script simple pour voir commits 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 affiche l'état des branches

51

Pour afficher les commits dans oldbranch mais pas newbranch:

git log newbranch..oldbranch 

Pour afficher la diff par ces commits (note il y a trois points):

git diff newbranch...oldbranch 

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

+0

Voir [le commentaire de Paul A Jungwirth] (http://stackoverflow.com/questions/1710894/using-git- show-all-commits-that-are-in-one-branche-mais-pas-les-autres # comment38269236_1710951) ci-dessus. Il semble que cela manquera à certains vieux commits? –

+1

Je ne suis pas sûr de ce que les anciens commits signifient. Les points doubles demandent essentiellement à Git de résoudre une plage de commits qui sont accessibles depuis une validation mais qui ne sont pas accessibles depuis une autre. Voici le doc avec une illustration de digram http://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges – Xuan

10

jimmyorr's answer ne fonctionne pas sous Windows. il aide à utiliser --not au lieu de ^ comme ceci:

git log oldbranch --not newbranch --no-merges 
+3

C'est exact, +1. Notez cependant que '^' est supporté sous Windows, mais doit être échappé, ce qui, dans Windows, est (autre) '^': 'git log oldbranch ^^ newbranch --no-merges'. – VonC

+0

@VonC a corrigé cette réponse avec votre commentaire. http://stackoverflow.com/a/4207176/2790048 –

+0

@NickVolynkin Bravo! – VonC

35

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

Première caisse de la branche que vous souhaitez supprimer:

git checkout [branch-to-delete]

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

git cherry -v master

sortie Exemple:

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

Remarque: L'indicateur -v doit inclure le message de validation avec le hachage SHA. Les lignes avec le '+' à l'avant sont dans la branche à supprimer, mais pas dans la branche principale. Ceux qui ont un '-' en face ont un commit équivalent en master.

Pour seulement les commits qui ne sont pas en maître, combiner cerise choisir avec grep:

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

sortie Exemple:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message 
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message 
+0

J'ai essayé ceci, mais cela rapporte toujours qu'il y a beaucoup de commits dans le fb (branche d'entité) 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 c'est pourquoi, mais je veux juste être certain. Si tel est le cas, je vais éviter d'écraser si possible; Je suis dans le "camp d'information non perdu". Je me demande s'il serait possible d'ajouter un mode d'affichage de journal qui peut afficher des fusions comme si elles étaient des rebasages pour garder l'historique propre et pourtant ne rien perdre. –

+0

Vous n'êtes pas sûr de votre scénario exact ici, mais si vous avez écrasé plusieurs validations en une seule et si vous comparez cela à une autre branche où les validations sont séparées, cela ne fonctionnera certainement pas. Dans ce cas, vous pouvez simplement utiliser l'utilitaire unix 'diff' pour comparer les différents fichiers. Ou, vous pouvez créer une branche temporaire et écraser tous les commits dans ce similaire à ce que vous avez fait avec la branche d'origine, puis utilisez ceci, ce qui je pense fonctionnerait. –

-3

Créer un Pull Demande via l'hébergement git service que vous utilisez.Si la branche a été entièrement fusionnée dans la branche de base, vous ne pourrez pas créer le nouveau PR.

Par exemple, sur GitHub:

There isn't anything to compare

Can't create a PR for branches that have been merged.

Cela ne veut pas utiliser git sur la ligne de commande, mais je trouve souvent il est utile d'utiliser les autres outils à votre disposition avec une vision claire modèle mental plutôt que de tenter de se souvenir d'une autre commande arcane git.

Questions connexes