Con Git, ¿cómo puedo saber si un commit en mi rama es descendiente de otro commit?
--is-ancestorsolución.
Con Git, ¿cómo puedo saber si un commit en mi rama es descendiente de otro commit?
--is-ancestorsolución.
Respuestas:
Si desea verificar esto mediante programación (por ejemplo, en el script), puede verificar si git merge-base A Bes igual a git rev-parse --verify A(entonces A es accesible desde B), o si lo es git rev-parse --verify B(entonces B es accesible desde A). git rev-parseaquí se necesita para convertir el nombre de confirmación en commit SHA-1 / commit id.
Usar git rev-listcomo en la respuesta VonC también es una posibilidad.
Editar: en Git moderno hay soporte explícito para esta consulta en forma de git merge-base --is-ancestor.
Si uno de los compromisos sobre los que está preguntando es una sugerencia de sucursal , entonces git branch --contains <commit>o git branch --merged <commit>podría ser una mejor solución no programática.
git checkout -b quickcheck <more-recent-commit-ID>y luego git branch --contains <older-commit-ID>(y luego git branch -D quickcheckdeshacerse de la rama temporal).
git merge-base --is-ancestorpor 2 años.
git branch --contains <commit>y git merge-base --is-ancestor ...: 3m40s vs 0.14s
Desde Git 1.8.0, esto se admite como una opción para merge-base:
git merge-base --is-ancestor <maybe-ancestor-commit> <descendant-commit>
Desde la página del manual:
--es-antepasado
Compruebe si el primero es ancestro del segundo y salga con el estado 0 si es verdadero o con el estado 1 si no. Los errores se señalan mediante un estado distinto de cero que no es 1.
Por ejemplo:
git merge-base --is-ancestor origin/master master; echo $?
git merge-base THING --is-ancestor OF_THING && echo yes || echo nopor ejemplo:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
git merge-base --is-ancestor -- commit commitfunciona para los hashes a mi lado con git2.1.4 (Debian / Devuan 7.10 jessie) y 1.9.1 (Ubuntu 14.04 de confianza) que son bastante antiguos ahora. Funciona incluso para Debian wheezy, si lo hace sudo apt-get install git/wheezy-backports.
Este tipo de operaciones se basa en la noción de rango de revisiones detalladas en la pregunta SO: " Diferencia en 'git log origin / master' vs 'git log origin / master ..' ".
git rev-list debería poder regresar de un commit, hasta otro si es accesible.
Entonces intentaría:
git rev-list --boundary 85e54e2408..0815fcf18a
0815fcf18a19441c1c26fc3495c4047cf59a06b9
8a1658147a460a0230fb1990f0bc61130ab624b2
-85e54e240836e6efb46978e4a1780f0b45516b20
(Las confirmaciones de límite tienen el prefijo -)
Si la última confirmación mostrada es la misma que la primera confirmación en el git rev-listcomando, entonces es una confirmación accesible desde la segunda confirmación.
Si el primer commit no es accesible desde el segundo, no git rev-listdebería devolver nada.
git rev-list --boundary A..B
terminaría por A, si Aes accesible desde B.
Es lo mismo que:
git rev-list --boundary B --not A
, con Buna referencia positiva y Auna referencia negativa .
Comenzará en By retrocederá a través del gráfico hasta que encuentre una revisión a la que se pueda acceder A.
Yo diría que si Aes directamente accesible B, se encontrará (y se mostrará, debido a la --boundaryopción) en Así mismo.
-85e54e2...el fragmento de código tiene un signo menos? también un error tipográfico: "... es lo mismo que la primera confirmación ..."
-significa que es un compromiso de límite. He editado la respuesta para aclarar eso, así como para actualizar los enlaces de documentos y corregir el error tipográfico para esta respuesta de 5 años.
Otra forma sería usar git logy grep.
git log --pretty=format:%H abc123 | grep def456
Esto producirá una línea de salida si commit def456 es un antecesor de commit abc123, o no hay salida de otra manera.
Por lo general, puede salirse con la suya omitiendo el --prettyargumento, pero es necesario si desea asegurarse de que solo busca a través de hashes de confirmación reales y no a través de comentarios de registro, etc.
--prettyusar --oneline: git log --oneline ce2ee3d | grep ec219ccfunciona muy bien
https://stackoverflow.com/a/13526591/895245 lo menciona, ahora para hacerlo más amigable para los humanos:
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 branch-sha1 commit-sha1
Dónde:
Si está usando git merge-base --is-ancestor, asegúrese de usar Git 2.28 (Q3 2020)
Con Git 2.28 (Q3 2020), algunos campos en " struct commit" que no tienen que estar siempre presentes se han movido para confirmar losas.
Ver commit c752ad0 , commit c49c82a , commit 4844812 , commit 6da43d9 (17 de junio de 2020) por Abhishek Kumar ( abhishekkumar2718) .
(Fusión por Junio C Hamano - gitster- en commit d80bea4 , 06 de julio de 2020)
commit-graph: presentarcommit_graph_data_slabFirmado por: Abhishek Kumar
La estructura commit se usa en muchos contextos. Sin embargo, los miembros
generationygraph_possolo se usan para operaciones relacionadas con gráficas de confirmación y, de lo contrario, desperdician memoria.Este desperdicio habría sido más pronunciado a medida que hacemos la transición al número de generación v2, que utiliza el número de generación de 64 bits en lugar de los 32 bits actuales.
Como a menudo se accede a ellos juntos, vamos a introducir struct
commit_graph_datay moverlos a unacommit_graph_datalosa.Si bien el conjunto de pruebas en general se ejecuta tan rápido como
master(serie: 26m48s,:master27m34s, más rápido en 2.87%), ciertos comandos comogit merge-base --is-ancestorse ralentizaron en un 40% como descubrió Szeder Gábor .
Después de minimizar el acceso a la losa de compromiso, la desaceleración persiste pero se acerca al 20%.Derrick Stolee cree que la desaceleración es atribuible al algoritmo subyacente más que a la lentitud del acceso de commit-slab y haremos un seguimiento en una serie posterior.
Construyendo sobre la respuesta de itub, en caso de que necesite hacer esto para todas las etiquetas en el repositorio:
for i in `git tag` ; do echo -ne $i "\t" ; git log --pretty=format:%H $i | (grep <commit to find> || echo ""); done