Avec Git, comment puis-je savoir si un commit dans ma branche est un descendant d'un autre commit?
--is-ancestor
solution.
Avec Git, comment puis-je savoir si un commit dans ma branche est un descendant d'un autre commit?
--is-ancestor
solution.
Réponses:
Si vous voulez vérifier cela par programme (par exemple dans un script), vous pouvez vérifier si git merge-base A B
est égal à git rev-parse --verify A
(alors A est accessible depuis B), ou si c'est le cas git rev-parse --verify B
(alors B est accessible depuis A). git rev-parse
est ici nécessaire pour convertir le nom du commit en commit SHA-1 / commit id.
Utiliser git rev-list
comme dans la réponse VonC est également possible.
Edit: dans Git moderne, il existe un support explicite pour cette requête sous la forme de git merge-base --is-ancestor
.
Si l'un des commits que vous demandez est une astuce de branche , alors git branch --contains <commit>
ou git branch --merged <commit>
pourrait être une meilleure solution non programmatique.
git checkout -b quickcheck <more-recent-commit-ID>
puis git branch --contains <older-commit-ID>
(et ensuite git branch -D quickcheck
de se débarrasser de la branche temporaire).
git merge-base --is-ancestor
de 2 ans.
git branch --contains <commit>
et git merge-base --is-ancestor ...
: 3m40s vs 0,14s
À partir de Git 1.8.0, ceci est pris en charge en tant qu'option pour merge-base
:
git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>
Depuis la page de manuel:
--est-ancêtre
Vérifiez si le premier est un ancêtre du second et quittez avec le statut 0 si vrai, ou avec le statut 1 dans le cas contraire. Les erreurs sont signalées par un état différent de zéro qui n'est pas 1.
Par exemple:
git merge-base --is-ancestor origin/master master; echo $?
git merge-base THING --is-ancestor OF_THING && echo yes || echo no
par exemple:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
git merge-base --is-ancestor -- commit commit
fonctionne pour les hachages à mes côtés avec git
2.1.4 (Debian / Devuan 7.10 jessie) et 1.9.1 (Ubuntu 14.04 trusty) qui sont plutôt anciens maintenant. Cela fonctionne même pour Debian wheezy, si vous le faites sudo apt-get install git/wheezy-backports
.
Ce type d'opérations repose sur la notion de plage de révisions détaillée dans la question SO: " Différence entre 'git log origin / master' vs 'git log origin / master ..' ".
git rev-list
devrait être en mesure de revenir d'un commit, jusqu'à un autre s'il est accessible.
Alors j'essaierais:
git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20
(Les commits de limite sont préfixés par -
)
Si le dernier commit affiché est le même que le premier commit dans la git rev-list
commande, alors il s'agit d'un commit accessible à partir du deuxième commit.
Si le premier commit n'est pas accessible à partir du second, git rev-list
ne doit rien renvoyer.
git rev-list --boundary A..B
finirait par A
, si A
est accessible à partir de B
.
C'est la même chose que:
git rev-list --boundary B --not A
, avec B
une référence positive et A
une référence négative .
Il commencera à B
et reviendra dans le graphique jusqu'à ce qu'il rencontre une révision accessible à partir de A
.
Je dirais que s'il A
est directement accessible depuis B
, il se rencontrera (et s'affichera, à cause de l' --boundary
option) A
.
-85e54e2...
dans l'extrait de code a-t-il un signe moins? également une faute de frappe possible: "... est le même que le premier commit ..."
-
signifie qu'il s'agit d'un commit de limite. J'ai modifié la réponse pour rendre cela plus clair, ainsi que pour actualiser les liens vers la documentation et corriger la faute de frappe pour cette réponse vieille de 5 ans.
Une autre façon serait d'utiliser git log
et grep
.
git log --pretty=format:%H abc123 | grep def456
Cela produira une ligne de sortie si commit def456 est un ancêtre de commit abc123, ou aucune sortie autrement.
Vous pouvez généralement vous en sortir en omettant l' --pretty
argument, mais cela est nécessaire si vous voulez vous assurer de ne rechercher que dans les hachages de validation réels et non dans les commentaires de journal, etc.
--pretty
utiliser --oneline: git log --oneline ce2ee3d | grep ec219cc
fonctionne très bien
https://stackoverflow.com/a/13526591/895245 le mentionne, maintenant pour le rendre plus convivial:
git-is-ancestor() (
if git merge-base --is-ancestor "$1" "$2"; then
echo 'ancestor'
elif git merge-base --is-ancestor "$2" "$1"; then
echo 'descendant'
else
echo 'unrelated'
fi
)
alias giia='git-is-ancestor'
git show-branch branche-sha1 commit-sha1
Où:
Si vous utilisez git merge-base --is-ancestor
, assurez-vous d'utiliser Git 2.28 (Q3 2020)
Avec Git 2.28 (Q3 2020), quelques champs de " struct commit
" qui ne doivent pas toujours être présents ont été déplacés vers les slabs de validation.
Voir commit c752ad0 , commit c49c82a , commit 4844812 , commit 6da43d9 (17 juin 2020) par Abhishek Kumar ( abhishekkumar2718
) .
(Fusionné par Junio C Hamano - gitster
- in commit d80bea4 , 06 juil.2020 )
commit-graph
: présentercommit_graph_data_slab
Signé par: Abhishek Kumar
Le struct commit est utilisé dans de nombreux contextes. Cependant, les membres
generation
etgraph_pos
ne sont utilisés que pour les opérations liées au graphe de validation et gaspillent de la mémoire.Ce gaspillage aurait été plus prononcé lorsque nous passons au numéro de génération v2, qui utilise le numéro de génération 64 bits au lieu des 32 bits actuels.
Comme ils sont souvent consultés ensemble, introduisons struct
commit_graph_data
et déplaçons-les vers unecommit_graph_data
dalle.Alors que l'ensemble de la suite de tests fonctionne aussi vite que
master
, (série: 26m48s,:master
27m34s, plus rapide de 2,87%), certaines commandes commegit merge-base --is-ancestor
ont été ralenties de 40% comme l'a découvert Szeder Gábor .
Après avoir minimisé l'accès à la dalle de validation, le ralentissement persiste mais est plus proche de 20%.Derrick Stolee pense que le ralentissement est attribuable à l'algorithme sous-jacent plutôt qu'à la lenteur de l'accès aux commit-slab et nous ferons un suivi dans une série ultérieure.
En vous basant sur la réponse d'itub, au cas où vous auriez besoin de le faire pour toutes les balises du référentiel:
for i in `git tag` ; do echo -ne $i "\t" ; git log --pretty=format:%H $i | (grep <commit to find> || echo ""); done