¿Podría cambiar su respuesta aceptada? A la mayoría le gusta la --is-ancestorsolución.
Robert Siemer
Respuestas:
51
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.
Posiblemente, la forma más rápida sería hacia 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).
clee
2
Dos posibles enfoques, ambos mucho peores que el de la respuesta de @ MattR.
jwg
66
@jwg: la respuesta de MattR es mejor, pero esta respuesta (y probablemente sea aceptada) es anterior a git 1.8.0 y git merge-base --is-ancestorpor 2 años.
Jakub Narębski
@ JakubNarębski Muy bien, lo siento.
jwg
2
En un gran repositorio (2 millones de commit), comparé la velocidad de git branch --contains <commit>y git merge-base --is-ancestor ...: 3m40s vs 0.14s
hagello
259
Desde Git 1.8.0, esto se admite como una opción para merge-base:
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.
¡Agradable! Aquí hay una secuencia de comandos de shell que envuelve esta respuesta en algo con salida accesible para humanos: gist.github.com/simonwhitaker/6354592
Simon Whitaker
1
En otras palabras: 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
user1735594
2
@smarber 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.
(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.
¡Oh, hombre, parece que tengo que regresar y trabajar en mis habilidades de scripting de Shell!
Lawrence I. Siden
1
pregunta: ¿por qué -85e54e2...el fragmento de código tiene un signo menos? también un error tipográfico: "... es lo mismo que la primera confirmación ..."
sdaau
1
@sdaau -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.
VonC
11
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.
La estructura commit se usa en muchos contextos. Sin embargo, los miembros generationy graph_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 una commit_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 como git 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.
--is-ancestor
solución.Respuestas:
Si desea verificar esto mediante programación (por ejemplo, en el script), puede verificar si
git merge-base A B
es igual agit rev-parse --verify A
(entonces A es accesible desde B), o si lo esgit rev-parse --verify B
(entonces B es accesible desde A).git rev-parse
aquí se necesita para convertir el nombre de confirmación en commit SHA-1 / commit id.Usar
git rev-list
como 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>
ogit branch --merged <commit>
podría ser una mejor solución no programática.fuente
git checkout -b quickcheck <more-recent-commit-ID>
y luegogit branch --contains <older-commit-ID>
(y luegogit branch -D quickcheck
deshacerse de la rama temporal).git merge-base --is-ancestor
por 2 años.git branch --contains <commit>
ygit merge-base --is-ancestor ...
: 3m40s vs 0.14sDesde Git 1.8.0, esto se admite como una opción para
merge-base
:Desde la página del manual:
Por ejemplo:
fuente
git merge-base THING --is-ancestor OF_THING && echo yes || echo no
por ejemplo:git merge-base my-feature-branch --is-ancestor master && echo yes || echo no
git merge-base --is-ancestor -- commit commit
funciona para los hashes a mi lado congit
2.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 hacesudo 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:
(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-list
comando, entonces es una confirmación accesible desde la segunda confirmación.Si el primer commit no es accesible desde el segundo, no
git rev-list
debería devolver nada.terminaría por
A
, siA
es accesible desdeB
.Es lo mismo que:
, con
B
una referencia positiva yA
una referencia negativa .Comenzará en
B
y retrocederá a través del gráfico hasta que encuentre una revisión a la que se pueda accederA
.Yo diría que si
A
es directamente accesibleB
, se encontrará (y se mostrará, debido a la--boundary
opción) enA
sí mismo.fuente
-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 log
ygrep
.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
--pretty
argumento, 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.fuente
--pretty
usar --oneline:git log --oneline ce2ee3d | grep ec219cc
funciona muy bienhttps://stackoverflow.com/a/13526591/895245 lo menciona, ahora para hacerlo más amigable para los humanos:
fuente
git show-branch branch-sha1 commit-sha1
Dónde:
fuente
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)fuente
Construyendo sobre la respuesta de itub, en caso de que necesite hacer esto para todas las etiquetas en el repositorio:
fuente