tag - ¿El árbol semisecreto vacío de git es confiable y por qué no hay un nombre simbólico para él?
qué tipos de etiquetas existen en git (2)
Git tiene un árbol vacío bien conocido, o al menos tipo de conocido, cuyo SHA1 es:
4b825dc642cb6eb9a060e54bf8d69288fbee4904
(Puedes ver esto en cualquier repositorio, incluso en uno nuevo, con git cat-file -t
y git cat-file -p
).
Si trabajas duro y eres muy cuidadoso puedes usar este árbol vacío para almacenar un directorio que no tiene archivos (consulta la respuesta a Cómo agrego un directorio vacío a un repositorio de git ), aunque no es realmente una gran idea.
Es más útil como argumento para git diff-tree
, que es lo que hace uno de los ganchos de muestra.
Lo que me pregunto es,
- ¿Cuán confiable es esto? ¿Es decir, alguna versión futura de git no tendrá un objeto git numerado
4b825dc642cb6eb9a060e54bf8d69288fbee4904
? - ¿Por qué no hay un nombre simbólico para el árbol vacío (o hay uno?).
(Una manera rápida y sucia de crear un nombre simbólico es poner el SHA1, por ejemplo, .git/Nulltree
. Desafortunadamente, tienes que hacer esto para cada repositorio. Parece mejor simplemente poner el número mágico en los scripts, etc. tener una aversión general a los números mágicos.)
Escribí una publicación de blog con dos formas diferentes de encontrar el hash: http://colinschimmelfing.com/blog/gits-empty-tree/
Si alguna vez cambiara por alguna razón, podría usar las dos formas a continuación para encontrarlo. Sin embargo, me sentiría muy seguro de usar el hash en los alias de .bashrc, etc., y no creo que vaya a cambiar pronto. Por lo menos, probablemente sería un lanzamiento importante de git.
Las dos formas son:
- La respuesta anterior:
git hash-object -t tree --stdin < /dev/null
- Simplemente ingrese un repositorio vacío y luego ejecute
git write-tree
en ese nuevo repositorio: el hash será generado por git write-tree.
Este hilo menciona:
Si no recuerda el árbol vacío sha1, siempre puede derivarlo con:
git hash-object -t tree /dev/null
O, como Ciro Santilli propone en los comentarios :
printf '''' | git hash-object --stdin -t tree
Entonces, creo que es más seguro definir una variable con el resultado de ese comando como su árbol sha1 vacío (en lugar de confiar en un "valor conocido").
Tenga en cuenta que verá que SHA1 aparece en algún repositorio GitHub cuando el autor quiere que su primer compromiso esté vacío (consulte la publicación del blog " Cómo inicializo mis repositorios Git "):
$ GIT_AUTHOR_DATE="Thu, 01 Jan 1970 00:00:00 +0000" GIT_COMMITTER_DATE="Thu, 01 Jan 1970 00:00:00 +0000" git commit --allow-empty -m ''Initial commit''
Te regalaré:
(Ver el árbol SHA1?)
Incluso puede volver a establecer una base de referencia de su historial existente sobre esa confirmación vacía (consulte " git: cómo insertar una confirmación como la primera, cambiando todas las demás ").
En ambos casos, no confía en el valor SHA1 exacto de ese árbol vacío.
Simplemente sigue una práctica recomendada inicializando tu repositorio con un primer compromiso vacío .
Para hacer eso:
git init my_new_repo
cd my_new_repo
git config user.name username
git config user.email email@com
git commit --allow-empty -m "initial empty commit"
Eso generará una confirmación con un SHA1 específico para su repositorio, nombre de usuario, correo electrónico, fecha de creación (lo que significa que el SHA1 del compromiso en sí mismo será diferente cada vez).
Pero el árbol al que hace referencia esa confirmación será 4b825dc642cb6eb9a060e54bf8d69288fbee4904
, el árbol vacío SHA1.
git log --pretty=raw
commit 9ed4ff9ac204f20f826ddacc3f85ef7186d6cc14
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 <====
author VonC <[email protected]> 1381232247 +0200
committer VonC <[email protected]> 1381232247 +0200
initial empty commit
Para mostrar solo el árbol de una confirmación (mostrar el árbol de confirmación SHA1):
git show --pretty=format:%T 9ed4ff9ac204f20f826ddacc3f85ef7186d6cc14
4b825dc642cb6eb9a060e54bf8d69288fbee4904
Si esa confirmación, haciendo referencia a un árbol vacío, es de hecho su primer compromiso, puede mostrar ese árbol vacío SHA1 con:
git log --pretty=format:%h --reverse | head -1 | xargs git show --pretty=format:%T
4b825dc642cb6eb9a060e54bf8d69288fbee4904
(y eso incluso funciona en Windows, con comandos Gnu On Windows )
Como se comenta a continuación , usando git diff <commit> HEAD
, esto mostrará todo su archivo en la rama actual HEAD:
git diff --name-only 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD
Nota: ese valor de árbol vacío se define formalmente en cache.h
.
#define EMPTY_TREE_SHA1_HEX /
"4b825dc642cb6eb9a060e54bf8d69288fbee4904"
Es ahora (Git 2.16, Q1 2018), uso en una estructura que ya no está vinculada a (solo) SHA1, como se ve en commit eb0ccfd :
Cambie las búsquedas de árbol vacío y blob para usar la abstracción de hash
Cambie los usos de
empty_tree_oid
yempty_blob_oid
para usar la abstraccióncurrent_hash
que representa el algoritmo hash actual en uso.
Ver más en " ¿Por qué Git no usa SHA más moderno? "