2009-12-07 16 views
13

Digamos que tengo un archivo A.cpp, y noto un error en la línea 15 del archivo. Digamos que el error es un "const" en una función que devuelve un puntero a una variable miembro, lo que significa que usar const en la función es técnicamente correcto pero semánticamente incorrecto. Me gustaría discutir la semántica con el autor que hizo el cambio.Usando git para encontrar la primera introducción de token en una línea específica de un archivo

Usando git, ¿hay alguna manera de averiguar qué revisión introdujo el token "const"? Más específicamente, me gustaría saber quién introdujo el token.

"git culpa" muestra quién hizo el último cambio en la línea, pero en realidad me gustaría encontrar la primera confirmación que contiene el token.

+0

¿No puede diferir cada revisión hasta que aparezca? Lo siento, no sé mucho sobre Git, pero eso es lo que haría para otros sistemas de control de fuente. –

+0

Sí, pero eso podría consumir mucho tiempo ... el historial del repositorio se remonta al menos a 3 años con varios miles de confirmaciones en este archivo. Parece una tarea bastante común, parece que habría una mejor manera de hacerlo. – paxos1977

+0

Ver también [git: encontrar una confirmación que introdujo una cadena] (http://stackoverflow.com/questions/5816134/git-finding-a-commit-that-introduced-a-string). –

Respuesta

13

git bisect es lo que estás buscando. Con este comando puedes encontrar rápidamente qué commit introdujo la const.

de iniciar el proceso con git bisect start, a continuación, marcar una versión antigua sin la const tan bueno con git bisect good y y la actual como bisect bad. Entonces el sistema te enviará a una versión en el medio. Puede verificar si la const mal está allí y marcar esa versión como buena o mala dependiendo de ella. Luego, el proceso se repite hasta que encuentre el compromiso incorrecto.

+4

Si puede escribir un script simple que sale con 1 si la constante está allí (es decir, un estado "malo"), llame a 'git bisect run myscript', siéntese y disfrute de que git haga el trabajo por usted ... –

1

Utilizo QGit para esto, selecciono las líneas de interés, y filtro sobre eso, entonces solo ve la lista de cambios para esa línea. Para una sola línea no es necesario saltar algunas revisiones.

a través de:

  • QGit abierta en repositorio
  • vista de estructura abierta
  • archivo hallazgo
  • línea hallazgo
  • de selección de línea de interés
  • de prensa 'revisión del filtro de líneas seleccionadas' botón, parece un embudo.
2

Si existía la línea sin el const token en algunos cometen que sabes, puede empezar por ahí y el uso de la bandera --reverse en git-culpa para encontrar la última revisión en la que la línea no tenía el token const . Luego solo mira la siguiente revisión en el archivo después de eso.

4

El cambio puede no haber sido siempre en la línea 15 de A.cpp, por lo tanto, utilice el contexto que lo rodea. Decir que fue una definición de const int foobar:

git grep 'const *int *foobar' \ 
    $(git log --reverse --pretty=format:%H -- A.cpp) -- \ 
    A.cpp | head -1 

Este busca hacia delante en el tiempo a través de todas las confirmaciones de la rama actual que toca A.cpp y encuentra la primera que contiene el patrón infractor. El resultado será SHA-1 de confirmación y la línea coincidente en su revisión de A.cpp.

Una vez que conozca la confirmación, use git show para obtener el autor.

28

Existen algunas formas posibles de hacerlo.

  • git blame, o mejor herramienta gráfica de culpa (como git gui blame o la vista en git instaweb/gitweb culpa) para navegar por la historia de una línea, que se remonta en la historia hasta que creas apropiado confirmación.

  • llamada "búsqueda pico", es decir git log -S con adecuada símbolo/expresión regular, para encontrar (lista) todas las confirmaciones en número de fichas dadas cambiado (que por lo general significa que se añadió o se elimina token dado), por ejemplo:

    git log --reverse -p -S'const int foobar' -- A.cpp 
    
  • git bisect donde "malo" significaría cometer el uno con 'const' donde hay que no debería ser (por ejemplo, pruebas usando grep).

Cuestiones relacionadas