2011-10-29 11 views
75

Wikipedia explica la detección de cambio de nombre automático:¿Cómo detecta git archivos similares para su detección de cambio de nombre?

Brevemente, dado un fichero en la revisión N, un archivo del mismo nombre en revisión N-1 es su antepasado predeterminado. Sin embargo, cuando no hay archivo con el mismo nombre en la revisión N-1, Git busca un archivo que existió solo en la revisión N-1 y es muy similar al archivo nuevo.

La detección del cambio de nombre aparentemente se reduce a la detección de archivos similares. ¿Ese algoritmo está documentado en alguna parte? Sería bueno saber qué tipo de transformaciones se detectan automáticamente.

Respuesta

75

Git rastrea el contenido del archivo, no los nombres de archivo. Así que cambiar el nombre de un archivo sin cambiar su contenido es fácil de detectar para git. (Git no hace un seguimiento, pero realiza detección;. Utilizando git mv o git rm y git add es efectivamente el mismo)

Cuando se añade un archivo al repositorio, el nombre de archivo está en el objeto árbol. El contenido del archivo real se agrega como un objeto binario grande (blob) en el repositorio. Git no agregará otro blob para archivos adicionales que contengan el mismo contenido. De hecho, Git no puede, ya que el contenido se almacena en el sistema de archivos; los primeros dos caracteres del hash son el nombre del directorio y el resto es el nombre del archivo que contiene. Por lo tanto, para detectar los cambios de nombre es una cuestión de comparar hashes.

Para detectar pequeños cambios en un archivo renombrado, Git utiliza ciertos algoritmos y un límite de umbral para ver si se trata de un cambio de nombre. Por ejemplo, eche un vistazo a la bandera -M para git diff. También hay valores de configuración como merge.renameLimit (la cantidad de archivos a considerar al realizar la detección de cambio de nombre durante una combinación).

Para comprender cómo git trata archivos similares (es decir, qué transformaciones de archivos se consideran cambios de nombre), explore las opciones de configuración y las marcas disponibles, como se mencionó anteriormente. No necesita ser considerado con el cómo. Para comprender cómo Git realmente lleva a cabo estas tareas, mira los algoritmos para encontrar diferencias en el texto y lee el código fuente de git.

Los algoritmos se aplican solo para fines de diff, merge y log; no afectan la forma en que los almacena git. Cualquier pequeño cambio en el contenido del archivo significa que se agrega un nuevo objeto. No hay delta o diff que suceda en ese nivel. Por supuesto, más adelante, los objetos pueden empaquetarse donde los deltas se almacenan en archivos de paquete, pero eso no está relacionado con la detección de cambio de nombre.

+2

Gran resumen, gracias. – mahemoff

+2

+1 para enfatizar en ** detectar ** palabra – akhyar

+28

_ "No necesita que se le tenga en cuenta cómo." _ - ¿Creí que esa era la pregunta? – bain

4

Hay muchos algoritmos que detectan similitudes entre los textos, y los sistemas de control de versiones a menudo los usan para almacenar solo la diferencia entre dos versiones. Las herramientas como WinMerge son lo suficientemente inteligentes como para detectar diferencias, incluso dentro de las líneas, por lo que no veo una razón por la cual estos algoritmos no se utilizarían para esta detección de cambio de nombre.

Aquí hay una discusión sobre algorithms to detect similar texts. Algunos de estos algoritmos podrían optimizarse para los lenguajes naturales, mientras que otros podrían funcionar mejor para el código fuente, pero en esencia son muy parecidos.

Cuestiones relacionadas