2012-10-06 10 views
5

Soy nuevo en git y acabo de descubrir "git bisect". ¿Cómo se usa generalmente cuando se puede verificar el error usando una prueba unitaria recién escrita (que no estaba allí de antemano)?Cómo usar git bisect: ¿Se utilizan pruebas unitarias para determinar la confirmación falsa?

Digamos que tenemos un repositorio que contiene pruebas unitarias, pero, como tantas veces, no estaban completas. En alguna versión descubrimos que una característica no funciona, pero sabemos que estaba en alguna versión anterior. Desafortunadamente esa característica no fue verificada por una prueba unitaria. Lo que me gustaría hacer ahora es:

  1. Escribe el caso de prueba (esto no funciona en un primer momento, por supuesto)
  2. Busca la introducción de cometer el error utilizando git biseccionar usando este caso de prueba
  3. Corrección de la error y confirmar el arreglo (y el caso de prueba)

Este caso de uso tiene un problema. Como git bisect revisa versiones antiguas, el caso de prueba recién insertado no estará allí, así que no puedo usarlo para verificar el error. Puedo intentar no realizar la prueba, pero mantenerla como un cambio local. Pero imaginando que el archivo de pruebas se modificó en alguna versión intermedia, es probable que me encuentre con conflictos de fusión.

¿Qué hacer? ¿Cómo se usa generalmente git bisect?

Respuesta

9

Normalmente utilizo bisect para identificar cuándo se introdujo un error, de modo que puedo ver una única confirmación para determinar la causa de un error. Esto es útil cuando sé que algo solía funcionar y ahora no. Primero selecciono o encuentro una confirmación anterior que funcionó, márquelo con git bisect good, marque la cabeza con git bisect bad, luego trabaje a través de la bisección hasta que git me diga la confirmación que introdujo el problema. A veces puedo escribir la prueba unitaria antes de comenzar este proceso, a veces no puedo escribir hasta que veo el código que introdujo el error.

Entonces, digamos que tengo la prueba de unidad, o algún otro código o script que necesito usar en cada punto al pasar por el proceso de gisexto. El alijo es útil para mantener eso mientras voy. Por lo tanto,

git stash save blah 
git bisect bad (and now I'm on a new commit) 
git stash pop 
mvn clean test 

git stash save blah 
git bisect good 
git stash pop 
mvn clean test 

y así sucesivamente.

2

En primer lugar, antes de intentar esto, asegúrese de que su git status es limpia - Estoy sugiriendo el uso de una secuencia de comandos que pueden invocar git reset --hard, por lo que cualquier cambio no comprometidos se perdería.

Una forma de hacerlo es copiar primero el código fuente de las pruebas más recientes en una ubicación que nunca se rastreó en el historial del repositorio (o en algún lugar fuera del repositorio). A continuación, escribir un guión que:

  1. copias las pruebas más recientes en su lugar en el árbol de fuentes
  2. ejecuta las pruebas, ahorrando el código de retorno.
  3. ¿Un git reset --hard para acabar con los cambios del paso 1
  4. salidas con el código de retorno salvados de 2.

Entonces, después de marcar dos confirmaciones como bueno y malo para dar git bisect lugar para empezar desde, puede usar git bisect run YOUR-SCRIPT para encontrar la primera confirmación donde las pruebas de unidades más recientes habrían fallado.

Este método es esencialmente lo que sugiere in the documentation for git bisect run, donde dice:

A menudo se puede encontrar que durante una sesión de bisect que desea tener modificaciones temporales (por ejemplo, s/#define DEBUG 0/#define DEBUG 1/en un archivo de encabezado, o "revisión que no tiene este compromiso necesita este parche aplicado para evitar otro problema, esta bisección no está interesado en") aplicado a la revisión que se está probando.

Para hacer frente a una situación así, después de que la bisección interna encuentre la siguiente revisión para probar, el script puede aplicar el parche antes de compilar, ejecutar la prueba real y luego decidir si la revisión (posiblemente con el parche necesario) Pasó la prueba y luego rebobinar el árbol al estado prístino. Finalmente, el script debe salir con el estado de la prueba real para permitir que el bucle de comando "git bisect run" determine el resultado final de la sesión de bisección.

1

No ha mencionado qué tecnología está utilizando, entonces usaré Ruby como ejemplo, que es con lo que estoy más familiarizado. El mismo principio debería aplicarse a otras tecnologías también, sin embargo.

  1. Coloque el archivo de prueba hasta la fecha fuera de su directorio de proyecto. Aquí voy a suponer que está en /tmp/my_test.rb

  2. en su repositorio, crear un pequeño script de shell, por ejemplo, test_runner.sh:

    #!/usr/bin/env sh  
    cp -f /tmp/my_test.rb test/my_test.rb # This will potentially overwrite some old test file 
    ruby test/my_test.rb # Change for whatever test runner you use 
    test_result=$? 
    git checkout test/my_test.rb # Undoes any changes that might have been made 
    exit $test_result 
    
  3. Marcos se compromete como bueno/malo, como se suele hacer con bisect.

  4. Usa git bisect run test_runner.sh y ve a tomar una taza de café mientras git encuentra tu error para ti.

Cuestiones relacionadas