Qual è la differenza tra `Commit hash`,` Parent Hash` e `Tree hash` in git?


12

Oggi sto imparando alcune conoscenze di base su Git leggendo questo documento online:

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

E in quel capitolo, inizierò a imparare git log --pretty=format:" "come mostrare le informazioni del registro a mio gusto.

Ma in qualche modo, ho visto nella tabella dei formati due opzioni simili, %Hper Commit Hash, %Pper Parent Hashe %Tper Tree Hash.

Li ho sperimentati sulla mia riga di comando, risulta che sono tutti valori hash della stessa lunghezza con valore diverso.

Ho cercato su Google e ho fatto lo stackoverflow, finora nessun accenno evidente.

Ne ho idea Hash value, è un checksum di quel commit git.

Ma cosa fa Parent Hashe cosa fa Tree hash?

  • PS: Ah, ho alcune idee ora, Parent Hashsignificava il valore hash dell'origine diretta di un ramo?

Risposte:


7

Hash del genitore:

$ git log --graph
*   commit c06c4c912dbd9ee377d14ec8ebe2847cf1a3ec7e
|\  Merge: 79e6924 3113760
| | Author: linjie <linjielig@gmail.com>
| | Date:   Mon Mar 14 16:02:09 2016 +0800
| |
| |     commit5
| |
| |     Merge branch 'dev'
| |
| * commit 31137606f85d8960fa1640d0881682a081ffa9d0
| | Author: linjie <linjielig@gmail.com>
| | Date:   Mon Mar 14 16:01:26 2016 +0800
| |
| |     commit3
| |
* | commit 79e69240ccd218d49d78a72f33002fd6bc62f407
|/  Author: linjie <linjielig@gmail.com>
|   Date:   Mon Mar 14 16:01:59 2016 +0800
|
|       commit4
|
* commit 7fd4e3fdddb89858d925a89767ec62985ba07f3d
| Author: linjie <linjielig@gmail.com>
| Date:   Mon Mar 14 16:01:00 2016 +0800
|
|     commit2
|
* commit 316dd3fb3c7b501bc9974676adcf558a18508dd4
  Author: linjie <linjielig@gmail.com>
  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

Puoi vedere commit4 e commit3 è padre di commit5 , commit2 è padre di commit3 e commit4 , commit1 è padre di commit2 .

Hash dell'albero:

$ 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 funzione del comando: stampa in modo grazioso il contenuto in <object>base al tipo.

git cat-file -p 

In git, tutto il contenuto viene archiviato come oggetti albero e BLOB, con alberi corrispondenti alle voci della directory UNIX e BLOB corrispondenti più o meno agli inode o al contenuto del file. Un singolo oggetto dell'albero contiene una o più voci dell'albero, ognuna delle quali contiene un puntatore SHA-1 a un BLOB o una sottostruttura con la modalità, il tipo e il nome file associati. Git normalmente crea un albero prendendo lo stato dell'area o dell'indice di gestione temporanea e scrivendo una serie di oggetti dell'albero da esso. Gli oggetti commit hanno le informazioni su chi ha salvato l'oggetto albero, quando sono stati salvati o perché sono stati salvati. Queste sono le informazioni di base che l'oggetto commit memorizza per te.

Conclusione:

Commit hash, Parent hash, Tree hash sono tutti SHA-1. Commit hash e Parent hash sono identici, tranne che l'hash Parent ha child. L'hash dell'albero è un oggetto Tree. Hash di commit e hash padre rappresentano un oggetto di commit.

Riferimento:

  1. Git Internals - Git Objects

  2. git-cat-file - Fornisce informazioni su contenuto o tipo e dimensioni per gli oggetti del repository


4

Un albero è una raccolta gerarchica di file e directory, non legata a nessun punto particolare della storia. Ad esempio, se crei un file e successivamente lo elimini (senza altri commit intermedi), finirai con lo stesso albero con cui hai iniziato.

Un commit è un punto nella storia del tuo progetto. Un commit specifica un albero, ma contiene anche altre informazioni come autore / committer e tempo, un messaggio di commit (in cui l'autore descrive cosa è cambiato) e, soprattutto, zero o più genitori, che sono lo stato precedente del repository. (Il tuo primo commit ha zero genitori. La maggior parte dei commit dopo ha un genitore durante lo sviluppo lineare e più di uno se ti unisci).

Puoi avere un'idea di come funziona con il git cat-file -pcomando, che stampa il contenuto di un determinato hash, indipendentemente dal tipo. Ad esempio, per esaminare il commit HEAD, è possibile eseguire:

$ git cat-file -p HEAD
tree 81ca1cb660ea79131336944df28b13b711d93557
parent 92b6b8fe9956866ace5397e060e7cc8ee1c76233
parent 7ea2575ed96d150ee19f70edea4bd42c7c2f0b83
author Mislav MarohniÄ <mislav.marohnic@gmail.com> 1436468108 -0700
committer Mislav MarohniÄ <mislav.marohnic@gmail.com> 1436468108 -0700

Merge pull request #951 from github/global-args

Avoid depending on a hardcoded list of git global flags

Per vedere l'albero all'interno di quel commit, è possibile cat-file -pche sia albero:

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

Allo stesso modo, se guardi i genitori, vedrai che anche questi sono impegni. Una scorciatoia per l'albero all'interno di un commit come revè rev^{tree}. Quindi il comando precedente avrebbe potuto essere scritto git cat-file -p HEAD^{tree}. Nota che rev^sta per il genitore di rev. Quando ci sono più i genitori, rev^1, rev^2, ecc Maggiori informazioni sono disponibili nella pagina man rev-parse git .


2

"Commit Hash" è l'hash per il commit corrente. Il commit a cui è associata la voce.

"Parent Hash" è l'hash per tutti i rami principali da cui proviene il commit.

"Hash dell'albero" è l'hash della directory corrente nel commit. L'hash è uguale all'hash che ha la directory se vista dalla directory padre git ls-files --stage --abbrev.

Riferimento:


1
cosa commit hassignifica all'inizio del tuo terzo paragrafo?
Zen
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.