Dado un id de confirmación, ¿cómo determinar si la rama actual contiene la confirmación?
156
Lo que intento hacer es una verificación de versión. Quiero asegurarme de que el código se mantenga por encima de una versión mínima. Entonces, necesito una manera de saber si la rama actual contiene una confirmación específica.
Consulte el duplicado propuesto para saber cómo encontrar todas las ramas que contienen una confirmación específica. Para averiguar si la rama actual contiene commit C , use el comando "plomería" git merge-base --is-ancestor. La rama actual contiene C si C es un antepasado de HEAD, entonces:if git merge-base --is-ancestor $hash HEAD; then echo I contain commit $hash; else echo I do not contain commit $hash; fi
torek
1
Hola, envíe esto como respuesta para que pueda seleccionarse como la respuesta correcta =)
Ben
1
@Ben: lo agregué como una respuesta wiki comunitaria.
Zitrax
1
@Remover: en los scripts de shell, cero es verdadero, no cero es falso: lo contrario de la convención C. /bin/truefue implementado originalmente como exit 0y /bin/falsecomo exit 1. (Conchas modernos entonces se han construido en.)
torek
Respuestas:
220
Hay múltiples formas de lograr este resultado. La primera opción ingenua es usar git logy buscar un commit específico usando grep, pero eso no siempre es preciso
git log | grep <commit_id>
Usted es mejor usar git branchdirectamente para encontrar todas las ramas que contienen dado COMMIT_IDel uso
git branch --contains $COMMIT_ID
El siguiente paso es descubrir la rama actual que se puede hacer desde git 1.8.1usar
Pero el comando anterior no devuelve verdadero o falso y hay una versión más corta que devuelve el código de salida 0 si commit está en la rama actual O el código de salida 1 si no
git merge-base --is-ancestor $COMMIT_ID HEAD
El código de salida es bueno, pero como desea una cadena trueo falsecomo respuesta, debe agregar un poco más y luego combinarlo con ifbash obtendrá
if [ 0 -eq $(git merge-base --is-ancestor $COMMIT_ID HEAD) ]; then echo "true"; else echo "false"; fi
Eso no es correcto; esto greppodría dar lugar a falsos positivos si git logmenciona el SHA de confirmación por otros motivos, por ejemplo, se menciona en un mensaje de confirmación como resultado de un puerto de otra rama.
El grepaquí también podría dar lugar a falsos positivos si hay otras ramificaciones que contienen el envío de datos cuyos nombres contienen también <branch-name>como una subcadena.
Adam Spires
1
Sí @AdamSpiers, Actualicé la respuesta con coincidencia exacta con el nombre de la sucursal porgrep -E '(^|\s)branchname$'
Sajib Khan
1
Según este comentario sobre la pregunta relacionada , puede ser útil agregar la opción -r("remoto") o -a("todo") git branchpara buscar ramas que no se puedan replicar en el clon de repositorio local.
sxc731
Esto no funcionó para mí, lo necesitaba git branch --all --contains <commit-id>
Arthur Tacca
7
Comentario extraído por @torek como respuesta:
Consulte el duplicado propuesto para saber cómo encontrar todas las ramas que contienen una confirmación específica.
Para averiguar si la rama actual contiene commit C, use el comando "plomería" git merge-base --is-ancestor. La rama actual contiene C si C es un ancestro de HEAD, entonces:
if git merge-base --is-ancestor $hash HEAD; then
echo I contain commit $hash
else
echo I do not contain commit $hash
fi
(Nota al margen: en los scripts de shell, un comando que sale de cero es "verdadero", mientras que uno que sale de cero es "falso").
Esto funciona mejor para mí, ya que también funcionaría en ramas remotas almacenadas en caché local, como remotes/origin/master, en las que git branch --containsno funcionará.
Esto cubre más que la pregunta de OP sobre la "rama actual", pero me parece tonto pedir una versión de "cualquier rama" de esta pregunta, así que decido publicar aquí de todos modos.
Es posible que obtenga ese error en 2 casos 1. Cuando el <nombre de rama> dado no contiene el <commit id> 2. La comprobación <nombre de rama> no es el <nombre de rama>
dado
0
Como esta pregunta tiene algunas buenas respuestas con guión, estoy agregando mis favoritos.
Este le mostrará, para los últimos $ncommits en $brqué ramas contiene cada uno:
git merge-base --is-ancestor. La rama actual contiene C si C es un antepasado deHEAD, entonces:if git merge-base --is-ancestor $hash HEAD; then echo I contain commit $hash; else echo I do not contain commit $hash; fi/bin/truefue implementado originalmente comoexit 0y/bin/falsecomoexit 1. (Conchas modernos entonces se han construido en.)Respuestas:
Hay múltiples formas de lograr este resultado. La primera opción ingenua es usar
git logy buscar un commit específico usandogrep, pero eso no siempre es precisoUsted es mejor usar
git branchdirectamente para encontrar todas las ramas que contienen dadoCOMMIT_IDel usoEl siguiente paso es descubrir la rama actual que se puede hacer desde
git 1.8.1usarY combinados juntos como
Pero el comando anterior no devuelve verdadero o falso y hay una versión más corta que devuelve el código de salida 0 si commit está en la rama actual O el código de salida 1 si no
El código de salida es bueno, pero como desea una cadena
trueofalsecomo respuesta, debe agregar un poco más y luego combinarlo conifbash obtendráfuente
greppodría dar lugar a falsos positivos sigit logmenciona el SHA de confirmación por otros motivos, por ejemplo, se menciona en un mensaje de confirmación como resultado de un puerto de otra rama.--format=format:%Hagit log.Obtenga una lista de sucursales que contiene la confirmación específica.
Compruebe si una rama tiene el compromiso específico.
Busque en la rama (digamos
feature) con coincidencia exacta .por ejemplo, si usted tiene 3 sucursales locales llaman
feature,feature1,feature2a continuación,También puede buscar en ambas
localyremoteramas (uso-a) o solo enremoteramas (uso-r).fuente
grepaquí también podría dar lugar a falsos positivos si hay otras ramificaciones que contienen el envío de datos cuyos nombres contienen también<branch-name>como una subcadena.grep -E '(^|\s)branchname$'-r("remoto") o-a("todo")git branchpara buscar ramas que no se puedan replicar en el clon de repositorio local.git branch --all --contains <commit-id>Comentario extraído por @torek como respuesta:
Consulte el duplicado propuesto para saber cómo encontrar todas las ramas que contienen una confirmación específica.
Para averiguar si la rama actual contiene commit C, use el comando "plomería"
git merge-base --is-ancestor. La rama actual contiene C si C es un ancestro de HEAD, entonces:(Nota al margen: en los scripts de shell, un comando que sale de cero es "verdadero", mientras que uno que sale de cero es "falso").
fuente
Para enumerar sucursales locales que contienen commit:
git branch --contains <commit-id>y para enumerar todas las ramas, incluidas las remotas, que contienen commit:
git branch -a --contains <commit-id>De manera similar para verificar si commit es en particular una rama:
git log <branch> | grep <commit_id>y si la rama no existe localmente el prefijo nombre de rama con
origin/fuente
-a. Gracias por ese consejo!Sí, otra alternativa:
Esto funciona mejor para mí, ya que también funcionaría en ramas remotas almacenadas en caché local, como
remotes/origin/master, en las quegit branch --containsno funcionará.Esto cubre más que la pregunta de OP sobre la "rama actual", pero me parece tonto pedir una versión de "cualquier rama" de esta pregunta, así que decido publicar aquí de todos modos.
fuente
Devolverá el nombre de la rama de destino si la identificación de confirmación existe en esa rama. De lo contrario, el comando fallará.
fuente
error: malformed object name 'branch-name'Como esta pregunta tiene algunas buenas respuestas con guión, estoy agregando mis favoritos.
Este le mostrará, para los últimos
$ncommits en$brqué ramas contiene cada uno:Este es similar pero hace lo mismo para una lista de ramas:
fuente