Question Trouver de quelle branche provient un commit git


Y a-t-il un moyen de savoir de quelle branche provient un commit vu son sha1?

Des points bonus si vous pouvez me dire comment accomplir cela en utilisant Ruby Grit.


467
2018-04-25 01:23


origine


Réponses:


Bien que Dav ait raison de dire que les informations ne sont pas stockées directement, cela ne signifie pas que vous ne pouvez jamais le découvrir. Voici quelques choses que vous pouvez faire.

Trouver les branches sur lesquelles le commit est activé

git branch --contains <commit>

Cela vous dira toutes les branches qui ont le don donné dans leur histoire. De toute évidence, cela est moins utile si les commits ont déjà été fusionnés.

Rechercher les reflogs

Si vous travaillez dans le référentiel dans lequel la validation a été effectuée, vous pouvez rechercher les refoulements de la ligne pour cette validation. Git-gc élague les Reflogs âgés de plus de 90 jours, donc si le commit est trop vieux, vous ne le trouverez pas. Cela dit, vous pouvez le faire:

git reflog show --all | grep a871742

pour trouver commit a871742. La sortie devrait être quelque chose comme ceci:

a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewrite

indiquant que le commit a été effectué sur la branche "completion". La sortie par défaut montre des hachages de commit abrégés, alors assurez-vous de ne pas rechercher le hash complet ou vous ne trouverez rien.

git reflog show est en fait juste un alias pour git log -g --abbrev-commit --pretty=oneline, donc si vous voulez jouer avec le format de sortie pour rendre différentes choses disponibles, c'est votre point de départ!

Si vous ne travaillez pas dans le référentiel où le commit a été fait, le mieux que vous puissiez faire dans ce cas est d'examiner les reflogs et de trouver quand le commit a été introduit pour la première fois dans votre repo; avec un peu de chance, vous avez récupéré la branche à laquelle elle était destinée. C'est un peu plus complexe, car vous ne pouvez pas marcher simultanément sur l'arbre de commit et sur les reflogs. Vous voudrez analyser la sortie reflog, en examinant chaque hachage pour voir si elle contient le commit souhaité ou non.

Trouver un commit de fusion ultérieur

Cela dépend du workflow, mais avec de bons workflows, les validations sont effectuées sur les branches de développement qui sont ensuite fusionnées. Vous pouvez faire ceci:

git log --merges <commit>..

pour voir les commits de fusion qui ont le commit donné comme ancêtre. (Si le commit n'a été fusionné qu'une seule fois, le premier devrait être la fusion que vous recherchez, sinon vous devrez en examiner quelques-uns, je suppose.) Le message de commit de fusion devrait contenir le nom de la branche qui a été fusionnée.

Si vous voulez pouvoir compter sur cela, vous pouvez utiliser le --no-ff option à git merge pour forcer la création de commit de fusion même dans le cas d'avance rapide. (Ne soyez pas trop impatient, cependant, qui pourrait devenir obscurcissant s'il est surutilisé.) VonC's répondre à une question connexe élabore utilement sur ce sujet.


664
2018-04-25 04:07



Mise à jour de décembre 2013:

sschuberth  commentaires

git-what-branch (Script Perl, voir ci-dessous) ne semble plus être maintenu.
git-when-merged est une alternative écrite en Python qui fonctionne très bien pour moi.

C'est basé sur "Rechercher un commit de fusion qui inclut un commit spécifique".

git when-merged [OPTIONS] COMMIT [BRANCH...]

Trouver quand un commit a été fusionné en une ou plusieurs branches.
  Trouver le commit de fusion qui a apporté COMMIT dans le (s) BRANCH spécifié (s).

Spécifiquement, recherchez le plus ancien engagement dans l’historique du parent BRANCH qui contient le COMMIT comme un ancêtre.


Réponse originale en septembre 2010:

Sébastien Douche juste twitté (16 minutes avant cette réponse SO):

git-what-branch: Découvrez quelle branche un commit est activé ou comment il est arrivé à une branche nommée

C'est un Script Perl de Seth robertson cela semble très intéressant:

SYNOPSIS

git-what-branch [--allref] [--all] [--topo-order | --date-order ]
[--quiet] [--reference-branch=branchname] [--reference=reference]
<commit-hash/tag>...

APERÇU

Dites-nous (par défaut) le premier chemin de causalité des commits et des fusions pour provoquer la validation demandée sur une branche nommée.
  Si une validation a été faite directement sur une branche nommée, c'est évidemment le premier chemin.

Par chemin causal le plus ancien, on entend le chemin qui a été fusionné en une branche nommée au plus tôt, par heure de validation (sauf si --topo-order est spécifié).

PERFORMANCE

Si de nombreuses branches (par exemple des centaines) contiennent la validation, le système peut prendre beaucoup de temps (pour une validation particulière dans l'arborescence Linux, l'exploration d'une branche a pris 8 secondes, mais il y avait plus de 200 branches candidates). à chaque engagement.
  Sélection d'un particulier --reference-branch --reference tag examiner sera des centaines de fois plus rapide (si vous avez des centaines de branches candidates).

EXEMPLES

 # git-what-branch --all 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4
 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 first merged onto master using the following minimal temporal path:
   v2.6.12-rc3-450-g1f9c381 merged up at v2.6.12-rc3-590-gbfd4bda (Thu May  5 08:59:37 2005)
   v2.6.12-rc3-590-gbfd4bda merged up at v2.6.12-rc3-461-g84e48b6 (Tue May  3 18:27:24 2005)
   v2.6.12-rc3-461-g84e48b6 is on master
   v2.6.12-rc3-461-g84e48b6 is on v2.6.12-n
   [...]

Ce programme ne prend pas en compte les effets de la sélection par cerise sur la validation d’intérêt, mais uniquement les opérations de fusion.


41
2017-09-22 18:27



Par exemple pour trouver quec0118fa commit est venu de redesign_interactions

* ccfd449 (HEAD -> develop) Require to return undef if no digits found
*   93dd5ff Merge pull request #4 from KES777/clean_api
|\  
| * 39d82d1 Fix tc0118faests for debugging debugger internals
| * ed67179 Move &push_frame out of core
| * 2fd84b5 Do not lose info about call point
| * 3ab09a2 Improve debugger output: Show info about emitted events
| *   a435005 Merge branch 'redesign_interactions' into clean_api
| |\  
| | * a06cc29 Code comments
| | * d5d6266 Remove copy/paste code
| | * c0118fa Allow command to choose how continue interaction
| | * 19cb534 Emit &interact event

Vous devriez courir:

git log c0118fa..HEAD --ancestry-path --merges

Et faites défiler pour trouver le dernier fusionner commettre. Lequel est:

commit a435005445a6752dfe788b8d994e155b3cd9778f
Merge: 0953cac a06cc29
Author: Eugen Konkov
Date:   Sat Oct 1 00:54:18 2016 +0300

    Merge branch 'redesign_interactions' into clean_api

UPD
Ou juste une commande:

git log 56a44a5..HEAD --ancestry-path --merges --oneline --color | tail -n 1

20
2017-10-29 13:50



Cette commande simple fonctionne comme un charme:

git name-rev <SHA>

Par exemple (où branche de test est le nom de la branche):

git name-rev 651ad3a
251ad3a remotes/origin/test-branch

Même cela fonctionne pour des scénarios complexes tels que: origin/branchA/ /branchB /commit<SHA1> /commit<SHA2>

Ici git name-rev commit<SHA2> résultats brancheB


10
2018-03-08 19:54



git branch --contains <ref> est la commande "porcelaine" la plus évidente pour faire ceci. Si vous voulez faire quelque chose de similaire avec seulement des commandes "plomberie":

COMMIT=$(git rev-parse <ref>) # expands hash if needed
for BRANCH in $(git for-each-ref --format "%(refname)" refs/heads); do
  if $(git rev-list $BRANCH | fgrep -q $COMMIT); then
    echo $BRANCH
  fi
done

(crosspost de cette réponse SO)


6
2017-10-23 18:08



L'option du pauvre est d'utiliser l'outil tig1 sur HEAD, recherchez la validation, puis suivez visuellement la ligne à partir de laquelle la validation est effectuée jusqu'à ce qu'une validation de fusion soit vue. Le message de fusion par défaut doit spécifier quelle branche est fusionnée à où :)

1 Tig est une interface en mode texte basée sur ncurses pour git. Cela fonctionne   principalement comme un navigateur de référentiel Git, mais peut également aider à la mise en scène   changements pour commettre au niveau du morceau et agir comme un pager pour la sortie de   diverses commandes Git.


4
2017-09-24 12:25



A titre expérimental, j'ai créé un hook post-commit qui stocke des informations sur la branche actuellement extraite dans les métadonnées de validation. J'ai aussi légèrement modifié gitk pour montrer cette information.

Vous pouvez le voir ici: https://github.com/pajp/branch-info-commits


3
2018-02-14 07:15



Si l'OP essaie de déterminer le histoire cela a été traversé par une branche quand un commit particulier a été créé ("trouver quelle branche un commit vient de son sha1"), alors sans le reflog il y a pas d'enregistrements dans la base de données d'objets git cela montre quelle branche nommée était liée à l’historique de validation.

(J'ai posté ceci comme réponse en réponse à un commentaire)

Espérons que ce script illustre mon propos:

rm -rf /tmp/r1 /tmp/r2; mkdir /tmp/r1; cd /tmp/r1
git init; git config user.name n; git config user.email e@x.io
git commit -m"empty" --allow-empty; git branch -m b1; git branch b2
git checkout b1; touch f1; git add f1; git commit -m"Add f1"
git checkout b2; touch f2; git add f2; git commit -m"Add f2"
git merge -m"merge branches" b1; git checkout b1; git merge b2
git clone /tmp/r1 /tmp/r2; cd /tmp/r2; git fetch origin b2:b2
set -x;
cd /tmp/r1; git log --oneline --graph --decorate; git reflog b1; git reflog b2;
cd /tmp/r2; git log --oneline --graph --decorate; git reflog b1; git reflog b2;

La sortie montre l'absence de moyen de savoir si le commit avec 'Add f1' provient de la branche b1 ou b2 du clone distant / tmp / r2

(dernières lignes du résultat ici)

+ cd /tmp/r1
+ git log --oneline --graph --decorate
*   f0c707d (HEAD, b2, b1) merge branches
|\  
| * 086c9ce Add f1
* | 80c10e5 Add f2
|/  
* 18feb84 empty
+ git reflog b1
f0c707d b1@{0}: merge b2: Fast-forward
086c9ce b1@{1}: commit: Add f1
18feb84 b1@{2}: Branch: renamed refs/heads/master to refs/heads/b1
18feb84 b1@{3}: commit (initial): empty
+ git reflog b2
f0c707d b2@{0}: merge b1: Merge made by the 'recursive' strategy.
80c10e5 b2@{1}: commit: Add f2
18feb84 b2@{2}: branch: Created from b1
+ cd /tmp/r2
+ git log --oneline --graph --decorate
*   f0c707d (HEAD, origin/b2, origin/b1, origin/HEAD, b2, b1) merge branches
|\  
| * 086c9ce Add f1
* | 80c10e5 Add f2
|/  
* 18feb84 empty
+ git reflog b1
f0c707d b1@{0}: clone: from /tmp/r1
+ git reflog b2
f0c707d b2@{0}: fetch origin b2:b2: storing head

0
2018-01-26 21:30



Pour trouver une succursale locale

grep -lR YOUR_COMMIT .git/refs/heads | sed 's/.git\/refs\/heads\///g'

Pour trouver une succursale distante

grep -lR $commit .git/refs/remotes | sed 's/.git\/refs\/remotes\///g'

-1
2017-07-05 05:58



Mis à part la recherche dans tout l'arbre jusqu'à ce que vous trouviez un hash correspondant, non.


-3
2018-04-25 01:30