He leído algunos artículos que dicen que git bisect
es increíble. Sin embargo, no soy un hablante nativo y no puedo entender por qué es increíble.
¿Podría alguien demostrar con algún ejemplo de código:
- ¿Cómo usarlo?
- ¿Es como
svn blame
?
git
git-bisect
Adaptador IA
fuente
fuente
Respuestas:
La idea detrás
git bisect
es realizar una búsqueda binaria en el historial para encontrar una regresión particular. Imagine que tiene el siguiente historial de desarrollo:Usted sabe que su programa no funciona correctamente en la
current
revisión y que estaba funcionando en la revisión0
. Por lo que la regresión fue probablemente introducido en una de las confirmaciones1
,2
,3
,4
,5
,current
.Puede intentar verificar cada confirmación, compilarla, verificar si la regresión está presente o no. Si hay una gran cantidad de confirmaciones, esto puede llevar mucho tiempo. Esta es una búsqueda lineal. Podemos hacerlo mejor haciendo una búsqueda binaria. Esto es lo que hace el
git bisect
comando. En cada paso, trata de reducir a la mitad el número de revisiones que son potencialmente malas.Usarás el comando así:
Después de este comando,
git
pagará un commit. En nuestro caso, será commit3
. Necesita construir su programa y verificar si la regresión está presente o no. También deberá indicargit
el estado de esta revisión, ya seagit bisect bad
si la regresión está presente ogit bisect good
no.Supongamos que la regresión se introdujo en commit
4
. Entonces la regresión no está presente en esta revisión, y le decimos que lo hagagit
.Luego verificará otro commit. Cualquiera
4
o5
(ya que solo hay dos confirmaciones). Supongamos que escogió5
. Después de una compilación, probamos el programa y vemos que la regresión está presente. Luego le decimos quegit
:Probamos la última revisión,
4
. Y como es el que introdujo la regresión, le decimos quegit
:En esta situación simple, sólo tuvimos que prueba 3 versiones (
3
,4
,5
) en lugar de 4 (1
,2
,3
,4
). Esta es una pequeña victoria, pero esto se debe a que nuestra historia es muy pequeña. Si el rango de búsqueda es de N commits, deberíamos esperar probar 1 + log2 N commits engit bisect
lugar de aproximadamente N / 2 commits con una búsqueda lineal.Una vez que haya encontrado el commit que introdujo la regresión, puede estudiarlo para encontrar el problema. Una vez hecho esto, puede
git bisect reset
volver a poner todo en el estado original antes de usar elgit bisect
comando.fuente
git bisect bad <rev> [<rev>...]
para marcar revisiones específicas como malas (o buenas congit bisect good <rev> [<rev>...]
).rev
puede ser cualquier identificador de revisión como un nombre de rama, una etiqueta, un hash de confirmación (o un prefijo único de hash de confirmación), ...git bisect reset
para volver a poner todo en la confirmación recientegit bisect run
bisección automáticaSi tiene un
./test
script automatizado que tiene el estado de salida 0 si la prueba es correcta, puede encontrar automáticamente el error conbisect run
:Esto supone, por supuesto, que si el script de prueba
./test
es rastreado, no desaparece en algún commit anterior durante la bisección.He descubierto que muy a menudo puedes escapar simplemente copiando el script del árbol fuera del árbol, y posiblemente jugando con
PATH
variables similares, y ejecutándolo desde allí.Por supuesto, si la infraestructura de prueba de la que
test
depende se rompe con los commits más antiguos, entonces no hay solución, y tendrá que hacer las cosas manualmente, decidiendo cómo probar los commits uno por uno.Sin embargo, he descubierto que el uso de esta automatización a menudo funciona, y puede ser un gran ahorro de tiempo para las pruebas más lentas que se encuentran en su cartera de tareas, donde puede dejar que se ejecute durante la noche y posiblemente identificar su error a la mañana siguiente, vale la pena. el intento
Mas consejos
Manténgase en la primera confirmación fallida después de la bisección en lugar de volver a
master
:start
+ inicialbad
ygood
de una vez:es lo mismo que:
Vea lo que se ha probado hasta ahora (por manual
good
y /bad
orun
):Salida de muestra:
Muestre referencias buenas y malas en git log para obtener una mejor noción del tiempo:
Esto solo muestra confirmaciones con una referencia correspondiente, lo que reduce el ruido real, pero incluye referencias de tipo autogeneradas:
que nos dicen qué compromisos hemos marcado como buenos o malos.
Considera este repositorio de prueba si quieres jugar con el comando.
El fracaso es rápido, el éxito es lento
Algunas veces:
Para esos casos, por ejemplo, suponiendo que la falla siempre ocurre dentro de 5 segundos, y si somos flojos para hacer la prueba más específica como realmente deberíamos, podemos usarla
timeout
como en:Esto funciona desde las
timeout
salidas124
mientras que la falla de lastest-command
salidas1
.Estados de salida mágica
git bisect run
es un poco exigente con los estados de salida:cualquier cosa por encima de 127 hace que la bisección falle con algo como:
En particular, una C
assert(0)
conduce aSIGABRT
ay sale con el estado 134, muy molesto.125 es mágico y hace que se salte la carrera
git bisect skip
.La intención de esto es ayudar a omitir compilaciones rotas debido a razones no relacionadas.
Ver
man git-bisect
para los detalles.Por lo tanto, es posible que desee utilizar algo como:
Probado en git 2.16.1.
fuente
test_script
conjunto de pruebas bien diseñado y modular, y ejecútelo desde el archivo separado mientras biseca. Cuando corrija, combine la prueba en el conjunto de pruebas principal.bisect run
especialmente útil cuando la prueba tarda mucho en terminar, y estoy bastante seguro de que el sistema de prueba no se romperá. De esta manera, puedo dejarlo ejecutándose en segundo plano, o de la noche a la mañana si consume demasiados recursos, sin perder el tiempo de cambio de contexto cerebral.TL; DR
Comienzo:
Bisecting: X revisions left to test after this (roughly Y steps)
Repetir:
El problema aún existe?
$ git bisect bad
$ git bisect good
Resultado:
Cuando termine:
fuente
git bisect good
para pasar al siguiente commit.Solo para agregar un punto más:
Podemos especificar un nombre de archivo o ruta
git bisect start
en caso de que sepamos que el error proviene de archivos particulares. Por ejemplo, supongamos que sabíamos que los cambios que causaron la regresión estaban en el directorio com / workingDir, entonces podemos ejecutargit bisect start com/workingDir
Esto significa que solo se verificarán las confirmaciones que cambiaron el contenido de este directorio, y esto hace que las cosas sean aún más rápidas.Además, si es difícil saber si un commit en particular es bueno o malo, puede ejecutarlo
git bisect skip
, lo que lo ignorará. Dado que hay suficientes otras confirmaciones, git bisect usará otra para limitar la búsqueda.fuente
$ git bisect ..
Básicamente una herramienta Git para depurar . 'Git Bisect' depura pasando por los commits anteriores desde su último commit de trabajo (conocido). Utiliza la búsqueda binaria para pasar por todas esas confirmaciones, para llegar a la que introdujo la regresión / error.$ git bisect start
# Bisecta de inicio$ git bisect bad
# indicando que el commit actual (v1.5) tiene el punto 'malo' de regresión / configuración$ git bisect good v1.0
# mencionándolo como el último buen compromiso de trabajo (sin regresión)Esta mención de los puntos 'malo' y 'bueno' ayudará a git bisect (búsqueda binaria) a elegir el elemento medio (commit v1.3). Si la regresión está allí en commit v1.3, la configurará como el nuevo punto 'malo', es decir ( Bueno -> v1.0 y Malo -> v1.3 )
o de manera similar si el commit v1.3 está libre de errores, lo configurará como el nuevo 'Punto bueno', es decir (* Bueno -> v1.3 y Malo -> v1.6).
fuente
Nota: los términos
good
ybad
no son los únicos que puede usar para marcar una confirmación con o sin una determinada propiedad.Git 2.7 (cuarto trimestre de 2015) introdujo nuevas
git bisect
opciones.Con documentación agregando:
Ver commit 06e6a74 , commit 21b55e3 , commit fe67687 (29 de junio de 2015) por Matthieu Moy (
moy
) .Ver commit 21e5cfd (29 de junio de 2015) por Antoine Delaite (
CanardChouChinois
) .(Fusionada por Junio C Hamano -
gitster
- en commit 22dd6eb , 05 oct 2015)fuente