2012-02-03 22 views
6

Estoy trabajando con libgit2sharp (un contenedor C# para libgit2) y he tenido problemas porque no tiene mucha de la funcionalidad que estoy esperando (espero poder contribuir con pronto, esto parece ser un proyecto realmente útil)Obtener cambios entre un commit y su padre con libgit2sharp

Lo que estoy tratando de hacer ahora es obtener una lista de los archivos modificados de un compromiso particular y su padre. No intentaré descubrir qué ha cambiado entre una combinación y sus dos padres. Estoy más interesado en compromisos regulares.

Estos chicos (https://github.com/libgit2/libgit2sharp/issues/89) están trabajando en algo similar. Creo que su procedimiento es una buena idea pero estoy un poco débil en mi comprensión de las partes internas de GIT (hay muchas guías en la guía del usuario final de GIT pero no tanto en la estructura interna)

Tengo curiosidad por saber cómo es sí mismo hace un comando "git diff". Supuestamente, GIT no almacena los deltas, sino más bien una versión completa del archivo (si no cambia, solo apunta a un SHA existente. Esta información se puede encontrar en varias fuentes, como aquí http://xentac.net/2012/01/19/the-real-difference-between-git-and-mercurial.html). Esto parece dificultar los cambios entre dos commits (en mi caso, un commit particular y su padre soltero) porque los datos no se almacenan como parte de la confirmación (lo cual es claro si se examina la clase Commit en Commit.cs de libgit2sharp) archivo).

Lo que puedo obtener acceso desde una confirmación es el árbol. ¿Tendría sentido hacer lo siguiente para encontrar esta información:

1) Comience en la confirmación deseada y camine por el árbol y almacene todos los valores SHA en un conjunto.

2) Comience por el padre para la confirmación deseada y camine por su árbol para almacenar todos sus valores blob SHA en otro conjunto.

3) Los SHA para los archivos cambiados serán los archivos que no estén en la intersección de los dos conjuntos.

El problema que veo con este enfoque es que no parece que haya una forma de obtener el nombre de archivo del valor SHA del blob (no veo nada que pueda hacer esto en el archivo Blob.cs de libgit2sharp).

Sé que hay muchas facetas de esta pregunta, pero son parte de este gran objetivo para obtener un dato particular de git.

Gracias.

+2

Tenga en cuenta que el mismo 'Blob' será apuntado a través de su SHA por diferentes' TreeEntries' con diferentes nombres de archivo. Esto sucederá cuando los archivos tengan el mismo contenido exacto. – nulltoken

Respuesta

7

lo que está buscando, una característicaárbol diffing, ya existe en libgit2 como se define en tree.h header.

La función git_tree_diff() compara dos Trees e invoca una devolución de llamada para cada diferencia (adición, actualización y eliminación). La función de devolución de llamada se está transfiriendo a una estructura git_tree_diff_data con la ruta de archivo del blob considerado, su estado, los modos de archivo anterior y actual y los SHA anteriores y actuales.

Desde la perspectiva de LibGit2Sharp, tendría más sentido que aprovechar la función libgit2 existente en lugar de volver a implementarlos en C#. Sin embargo, incluso si puede obtener algo de inspiración de los existentes Interop definitions, las cosas tienden a ser rápidamente complicadas al tratar de domesticar la capa .Net/interoperabilidad nativa.

Desde su punto de vista (como una contribución a LibGit2Sharp puede no su objetivo principal;)), otra opción sería la de aportar el código C a C#, basándose en las características existentes LibGit2Sharp a caminar por los árboles. git_tree_diff() (y sus funciones de satélite) es una pieza muy limpia de código, y aunque hace un trabajo bastante complejo, los comentarios son muy claros y útiles.

Referencias:

  • La función git_tree_diff() se implementa en src/tree.c
  • pruebas que ejercen esta función están disponibles here

Nota: Con el fin t o enlace git_tree_diff(), se debe abrir un problema en libgit2 tracker solicitando que la definición del método se actualice para que sea GIT_EXTERN 'd. De lo contrario, no será accesible desde .Net.

ACTUALIZACIÓN

lanzamiento v0.9.0 de LibGit2Sharp finalmente trajeron el árbol a árbol diffing función.

TreeChanges changes = repo.Diff.Compare(fromTree, newTree);

propiedades expuestas son:

  • líneas añadidas/modificados
  • Colecciones de cambios TreeEntry por tipo de cambio
  • el diff (por ejemplo, añadir, modificar, ....) Parche

Puede encontrar más información sobre esta característica y cómo aprovechar la TreeChanges echando un vistazo a unit tests in DiffTreeToTreeFixture.cs.

+0

¡Muchas gracias por la gran respuesta! Me di cuenta de que eres un colaborador activo de libgit2 y libgit2sharp. Estoy muy interesado en ayudar con este proyecto, así que veré si puedo aprovechar la función libgit2 en libgit2sharp. Aunque no sé si alguno de los proyectos está buscando otro colaborador. – bashirs

+0

A cada FOSS le gusta un buen parche ;-) – nulltoken

Cuestiones relacionadas