¿Cuál es la diferencia entre `Commit hash`,` Parent Hash` y `Tree hash` en git?

12

Hoy estoy aprendiendo algunos conocimientos básicos de git leyendo este documento en línea:

http://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-Hi

Y en ese capítulo, empiezo a aprender a usar git log --pretty=format:" "para mostrar información de registro a mi gusto.

Pero de alguna manera, vi en la tabla de formatos dos opciones similares, %Hpara Commit Hash, %Ppara Parent Hashy %Tpara Tree Hash.

Los experimenté en mi línea de comando, resulta que todos son valores hash de la misma longitud con valores diferentes.

Busqué en Google y el stackoverflowed, no hay indicios obvios hasta ahora.

Tengo una idea sobre esto Hash value, es una suma de comprobación de ese git commit.

¿Pero qué hace Parent Hashy qué hace Tree hash?

  • PD: Ah, tengo algunas ideas ahora, ¿ Parent Hashsignificaba el valor hash del origen directo de una rama?
zen
fuente

Respuestas:

7

Padres hash:

$ git log --graph
*   commit c06c4c912dbd9ee377d14ec8ebe2847cf1a3ec7e
|\  Merge: 79e6924 3113760
| | Author: linjie <[email protected]>
| | Date:   Mon Mar 14 16:02:09 2016 +0800
| |
| |     commit5
| |
| |     Merge branch 'dev'
| |
| * commit 31137606f85d8960fa1640d0881682a081ffa9d0
| | Author: linjie <[email protected]>
| | Date:   Mon Mar 14 16:01:26 2016 +0800
| |
| |     commit3
| |
* | commit 79e69240ccd218d49d78a72f33002fd6bc62f407
|/  Author: linjie <[email protected]>
|   Date:   Mon Mar 14 16:01:59 2016 +0800
|
|       commit4
|
* commit 7fd4e3fdddb89858d925a89767ec62985ba07f3d
| Author: linjie <[email protected]>
| Date:   Mon Mar 14 16:01:00 2016 +0800
|
|     commit2
|
* commit 316dd3fb3c7b501bc9974676adcf558a18508dd4
  Author: linjie <[email protected]>
  Date:   Mon Mar 14 16:00:34 2016 +0800

     commit1

$ git log --pretty=format:'%<(82)%P %s'
79e69240ccd218d49d78a72f33002fd6bc62f407 31137606f85d8960fa1640d0881682a081ffa9d0  commit5
7fd4e3fdddb89858d925a89767ec62985ba07f3d                                           commit4
7fd4e3fdddb89858d925a89767ec62985ba07f3d                                           commit3
316dd3fb3c7b501bc9974676adcf558a18508dd4                                           commit2
                                                                                   commit1

Puede ver commit4 y commit3 es padre de commit5 , commit2 es padre de commit3 y commit4 , commit1 es padre de commit2 .

Hash de árbol:

$ git log --pretty=format:'%T %s'
f3c7cee96f33938631a9b023ccf5d8743b00db0e commit5
e0ecb42ae45ddc91c947289f928ea5085c70b208 commit4
d466aea17dc07516c449c58a73b2dc3faa9d11a1 commit3
b39f2e707050e0c5bbb3b48680f416ef05b179ba commit2
5706ec2b32605e27fa04cbef37d582325d14dda9 commit1

$ git cat-file -p f3c7ce
100644 blob 8bb2e871e94c486a867f5cfcbc6f30d004f6a9e5    dev
100644 blob 47f16c8e00adba77ec5c176876e99c8e9f05d69b    master

$ git cat-file -p 5706ec
100644 blob fc0bfde0d44bb4d6c7d27b6e587ebedd34ba5911    master

La función del comando: Pretty-print el contenido de <object>basado en su tipo.

git cat-file -p 

En git, todo el contenido se almacena como objetos de árbol y blob, con árboles que corresponden a entradas de directorio UNIX y blobs que corresponden más o menos a inodos o contenido de archivos. Un único objeto de árbol contiene una o más entradas de árbol, cada una de las cuales contiene un puntero SHA-1 a un blob o subárbol con su modo, tipo y nombre de archivo asociados. Git normalmente crea un árbol tomando el estado de su área de preparación o índice y escribiendo una serie de objetos de árbol a partir de él. Los objetos de confirmación tienen la información sobre quién guardó el objeto del árbol, cuándo se guardaron o por qué se guardaron. Esta es la información básica que el objeto de confirmación almacena para usted.

Conclusión:

El hash de commit, el hash padre, el hash de árbol son todos SHA-1. Commit hash y Parent hash es idéntico excepto que Parent hash tiene child. El hash del árbol es representar un objeto Tree. Commit hash y Parent hash representan un objeto commit.

Referencia:

  1. Git Internals - Objetos Git

  2. git-cat-file: proporciona información de contenido o tipo y tamaño para objetos de repositorio

linjie
fuente
4

Un árbol es una colección jerárquica de archivos y directorios, no vinculada a ningún punto particular en la historia. Por ejemplo, si crea un archivo y luego lo elimina (sin otras confirmaciones intermedias), terminará con el mismo árbol con el que comenzó.

Un commit es un punto en la historia de su proyecto. Un commit especifica un árbol, pero también contiene otra información, como autor / committer y hora, un mensaje de compromiso (en el que el autor describe qué cambió) y, lo más importante, cero o más padres, que son el estado anterior del repositorio. (Su primer commit tiene cero padres. La mayoría de los commits tienen un padre durante el desarrollo lineal y más de uno si se fusiona).

Puede tener una idea de cómo funciona esto con el git cat-file -pcomando, que imprime el contenido de un hash en particular, independientemente del tipo. Por ejemplo, para ver la confirmación HEAD, puede ejecutar:

$ git cat-file -p HEAD
tree 81ca1cb660ea79131336944df28b13b711d93557
parent 92b6b8fe9956866ace5397e060e7cc8ee1c76233
parent 7ea2575ed96d150ee19f70edea4bd42c7c2f0b83
author Mislav MarohniÄ <[email protected]> 1436468108 -0700
committer Mislav MarohniÄ <[email protected]> 1436468108 -0700

Merge pull request #951 from github/global-args

Avoid depending on a hardcoded list of git global flags

Para ver el árbol dentro de ese commit, puedes cat-file -phacerlo:

$ git cat-file -p 81ca1cb660ea79131336944df28b13b711d93557
100644 blob 730f77a3be502cfe6769c1305c0b59c22274caf5        .gitignore
100644 blob bcbd000f6b9ad5b0510f804ac4a3b19306b39c03        .travis.yml
100644 blob da71aa1fa3c3ae47b2fe5e6245ce2eea1586e278        CONTRIBUTING.md
...

Del mismo modo, si miras a los padres, verás que esos son compromisos también. Una abreviatura para el árbol dentro de una confirmación como reves rev^{tree}. Entonces el comando anterior podría haber sido escrito git cat-file -p HEAD^{tree}. Tenga en cuenta que rev^significa el padre de rev. Cuando hay varios padres, rev^1, rev^2, etc. Más información está disponible en la página del manual de rev-parse git .

usuario3188445
fuente
2

"Commit Hash" es el hash para el commit actual. La confirmación con la que está asociada la entrada.

"Hash principal" es el hash para cualquier rama principal de la que proviene el commit.

El "hash de árbol" es el hash del directorio actual en el commit. El hash es igual al hash que tiene el directorio si se ve desde el directorio padre con git ls-files --stage --abbrev.

Referencia:

Braiam
fuente
1
¿Qué commit hassignifica al comienzo de su tercer párrafo?
Zen