2011-06-17 12 views
35

Alguien tomó una versión (desconocida para mí) de Moodle, aplicó muchos cambios dentro de un directorio y la lanzó (tree here).Git: ¿Cómo puedo encontrar una confirmación que coincida más estrechamente con un directorio?

¿Cómo puedo determinar qué compromiso del proyecto original fue editado para formar este árbol?

esto me permitiría formar una rama en la confirmación adecuada con este parche. Seguramente vino de las ramas 1.8 o 1.9, probablemente de una etiqueta de lanzamiento, pero diferir entre las confirmaciones particulares no me ayuda mucho.

Postmortem Actualización:knittl's answer me tiene tan cerca como voy a conseguir. Primero agregué mi repositorio de parches como el control remoto "extranjero" (sin confirmaciones en común, eso está bien), luego hice diffs en los bucles con un par de opciones de formato. El primero utiliza el formato --shortstat:

for REV in $(git rev-list v1.9.0^..v1.9.5); do 
    git diff --shortstat "$REV" f7f7ad53c8839b8ea4e7 -- mod/assignment >> ~/rdiffs.txt; 
    echo "$REV" >> ~/rdiffs.txt; 
done; 

El segundo solo contaron los cambios de línea en un diff unificado sin contexto:

for REV in $(git rev-list v1.9.0^..v1.9.5); do 
    git diff -U0 "$REV" f7f7ad53c8839b8ea4e7 -- mod/assignment | wc -l >> ~/rdiffs2.txt; 
    echo "$REV" >> ~/rdiffs2.txt; 
done; 

Había miles de confirmaciones para cavar a través, pero this one parece haber el partido más cercano.

+1

Si usted puede encontrar alguna prueba significativa que se puede aplicar a un particular, se comprometen de la cesión temporal Moodle y la inicial comprometerse de moodle-matriz de valoración para determinar si éste ocurrió antes o después de la primera, puede usar 'git bisect' para regresar rápidamente a la confirmación de la fuente. Echa un vistazo a 'git bisect --help' para los flacos. –

+0

Gracias usó esto ahora con gran éxito. Used 'cat rdiffs.txt | grep -oe '[0-9] * inserciones' | ordenar -n | head -n 10' (y similar) para reducir la cantidad más baja de cambios sin tener que realizar ninguna búsqueda manual. Solo mencionando en caso de que alguien encuentre la información adicional a mano. –

Respuesta

11

puede escribir una secuencia de comandos, que diferencia el árbol dado de un rango de revisión en su repositorio.

suponer que primero descargar el árbol cambiada (sin antecedentes) en nuestro propio repositorio:

git remote add foreign git://… 
git fetch foreign 

entonces la salida del diffstat (en forma abreviada) para cada revisión que queremos hacer coincidir en contra:

for REV in $(git rev-list 1.8^..1.9); do 
    git diff --shortstat foreign/master $REV; 
done 

mirada para el comprometerse con la menor cantidad de cambios (o utilizar algún mecanismo de clasificación)

+0

Gracias. Actualicé la pregunta con lo que hice exactamente. –

-2

¿Qué le parece usar 'git blame'? Le mostrará, para cada línea, quién lo cambió y en qué revisión.

+3

esto solo funciona para commits con historial, y ese es exactamente el problema aquí: falta de historial y puntos de ramificación – knittl

0

Cómo sobre el uso de git para crear un parche de todas las versiones de 1,8. y 1.9 a esta nueva versión. Luego podría ver qué parche tiene más 'sentido'.

Por ejemplo, si el parche 'elimina' muchos métodos, entonces probablemente no sea este lanzamiento, sino uno anterior. Si el parche tiene muchas secciones que no tienen sentido como una sola edición, entonces probablemente tampoco sea esta versión.

Y así sucesivamente ... En realidad, lamentablemente, no existe un algoritmo para hacer esto perfectamente. Tendré que ser heurístico.

1

Esta fue mi solución:

#!/bin/sh 

start_date="2012-03-01" 
end_date="2012-06-01" 
needle_ref="aaa" 

echo "" > /tmp/script.out; 
shas=$(git log --oneline --all --after="$start_date" --until="$end_date" | cut -d' ' -f 1) 
for sha in $shas 
do 
    wc=$(git diff --name-only "$needle_ref" "$sha" | wc -l) 
    wc=$(printf %04d $wc); 
    echo "$wc $sha" >> /tmp/script.out 
done 
cat /tmp/script.out | grep -v ^$ | sort | head -5 
+0

Terminé teniendo que especificar la rama (principal), eliminando --all, porque también buscó el needle_ref, dando como resultado cero diffs. – Kyle

+1

Como @kyle menciona; este script es bueno, excepto la última línea, que termina eligiendo el diff más bajo - si el rango de fechas incluye el checkin que estamos comparando (es decir, el needle_ref), entonces eso gana con 0 archivos diferentes. Recomiendo cambiar la última línea a: "cat /tmp/script.out | grep -v^$ | sort | head -5" - esto mostrará los 5 checkins con el menor número de cambios de archivo. – thetoolman

+0

@thetoolman Editado. – mattalxndr

Cuestiones relacionadas