2012-01-15 9 views
10

En aras de un experimento, digamos que su git log identifica los siguientes compromete¿El SHA-1 de confirmaciones se calcula solo en función del contenido del árbol?

commit 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438 // added 2nd file 
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 

Después de cometer, .git/refs/heads/master puntos a 16bc8486fb34cf9a6faf0f7df606ae72ad9ea438.

Digamos que, después de esto, puedo editar manualmente el archivo .git/refs/heads/master para apuntar a 9188f9a25b045f130b08888bc3f638099fa7f212

En este punto, git status reconoce que un nuevo archivo no comprometida está en necesidad de un poco de atención. Este es el mismo archivo que mi segundo commit se encargó antes.

si lo hago COMPROMÉTANSE .. git log muestra ahora

commit b317f67686f9e6ab1eaabf47073b401d677205d5 // 2nd file committed for the 2nd time 
commit 9188f9a25b045f130b08888bc3f638099fa7f212 // initial commit 

Pregunta 1:

Se dará cuenta de que SHA hashes son diferentes entre la primera vez que cometí un segundo archivo y ahora. ¿Porqué es eso? El contenido del archivo no cambió, sigue siendo el mismo archivo exacto.

Pregunta 2

En este punto, ¿qué pasó con el segundo original comprometerse? Cuando lo hago git show 16bc8486, muestra este compromiso. Sin embargo, no aparece en el historial git log.

+1

Lectura interesante: http://book.git-scm.com/1_the_git_object_model.html – Mat

Respuesta

14

Pregunta 1: Porque el hash se genera teniendo todo en cuenta, incluidos los metadatos de confirmación (que a su vez contiene la fecha y la hora).

Pregunta 2: git log muestra el registro de la rama actual. La confirmación 16bc8486 no forma parte de ella. Por lo que sé (no estoy del todo seguro), el recolector de basura se lo llevará tarde o temprano, si lo encuentra sin referencia alguna (git gc --help) ..

+0

En Q2, 'git branch' solo muestra una rama en existencia en este punto - * master. ¿De qué rama es parte el archivo antiguo? – JAM

+0

@JAM: no es parte de ninguna rama, por lo que es candidato para la recolección de basura. Puedes "rescatarlo" creando una rama explícitamente en esa confirmación 'git branch nombre_rama commit_hash'. – Mat

+0

@Mat, si pasa algún tiempo y ese hash no está disponible, ¿es posible recuperarlo de alguna manera? – JAM

2

El SHA1 se calcula a partir del diff y todos metadatos de esta confirmación (incluidos el autor y el autor, la marca de tiempo y otros datos).

Para su segunda pregunta, la confirmación de datos todavía está presente pero ya no forma parte de ninguna rama en vivo. A veces, Git ejecutará una colección de basura donde se eliminarán varias cosas eliminadas. Notarás que una vez que lo ejecutas manualmente usando git gc, la confirmación no referenciada desaparecerá y ni siquiera se podrá acceder con git show.

6

Los valores de sha1 para cada uno de los blobs de serán idénticos en ambos casos si tiene el mismo contenido (incluso si se cambia el nombre del archivo).

Del mismo modo, los valores de sha1 para los árboles de los blobs de archivos serán los mismos si tienen los mismos nombres de archivo.

Sin embargo en la parte superior tenemos la cometer que contendrá el enlace sin cambios a la confirmación anterior, el árbol de la parte superior, el autor y commiter, pero como dijo KingCrunch, el autor y commiter fecha se diferente , por lo que el sha1 de commit sha1 será diferente.

Puede hacer que sean iguales si establece deliberadamente la fecha del autor y del compromiso utilizando las variables de entorno para que no se modifiquen.

+0

Corolario adicional; Si uno los hace idénticos, serán idénticos en lo que respecta al almacén de objetos y los gráficos de ramas. Será como si la división inicial, pero idéntica, nunca hubiera sucedido: ¡son indistinguibles! Feliz cacería. –

Cuestiones relacionadas