Qual é a diferença entre `Commit hash`,` Parent Hash` e `Tree hash` no git?

12

Hoje estou aprendendo alguns conhecimentos básicos sobre o git lendo este documento on-line:

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

E, nesse capítulo, estou começando a aprender a usar git log --pretty=format:" "as informações de log ao meu gosto.

Mas de alguma forma, vi na tabela de formato duas opções semelhantes, %Hpara Commit Hash, %Ppara Parent Hashe %Tpara Tree Hash.

Eu experimentei-os na minha linha de comando, pois todos são valores de hash do mesmo comprimento com valores diferentes.

Eu pesquisei e transbordei, sem pistas óbvias até agora.

Eu tenho idéia sobre isso Hash value, é uma soma de verificação desse commit do git.

Mas o que faz Parent Hashe Tree hashfaz?

  • PS: Ah, eu tenho algumas idéias agora, o que Parent Hashsignifica o valor de hash da origem direta de um ramo?
zen
fonte

Respostas:

7

Hastes pai:

$ 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

Você pode ver commit4 e commit3 é pai de commit5 , commit2 é pai de commit3 e commit4 , commit1 é pai de commit2 .

Hash de árvore:

$ 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

A função do comando: Imprima o conteúdo com <object>base no seu tipo.

git cat-file -p 

No git, todo o conteúdo é armazenado como objetos de árvore e blob, com árvores correspondentes às entradas do diretório UNIX e blobs correspondendo mais ou menos a inodes ou conteúdo de arquivo. Um único objeto de árvore contém uma ou mais entradas de árvore, cada uma contendo um ponteiro SHA-1 para um blob ou subárvore com seu modo, tipo e nome de arquivo associados. O Git normalmente cria uma árvore, tomando o estado da sua área de preparação ou índice e gravando uma série de objetos da árvore. Os objetos de confirmação têm informações sobre quem salvou o objeto em árvore, quando eles salvaram ou por que eles foram salvos. Essas são as informações básicas que o objeto de confirmação armazena para você.

Conclusão:

Confirmar hash, pai hash, árvore hash são todos SHA-1. Confirmar hash e pai hash é idêntico, exceto pai hash filho. O hash da árvore é um objeto da árvore. O hash de confirmação e o hash pai representam um objeto de confirmação.

Referência:

  1. Git Internals - Objetos Git

  2. git-cat-file - Fornece informações de conteúdo ou tipo e tamanho para objetos de repositório

linjie
fonte
4

Uma árvore é uma coleção hierárquica de arquivos e diretórios, não vinculada a nenhum ponto específico da história. Por exemplo, se você criar um arquivo e depois excluir o arquivo (sem nenhuma outra confirmação intermediária), você terminará na mesma árvore em que iniciou.

Uma confirmação é um ponto na história do seu projeto. Uma confirmação especifica uma árvore, mas também contém outras informações como autor / confirmador e hora, uma mensagem de confirmação (na qual o autor descreve o que mudou) e, mais importante, zero ou mais pais, que são o estado anterior do repositório. (Seu primeiro commit possui zero pais. A maioria dos commit depois disso tem um pai durante o desenvolvimento linear e mais de um se você mesclar.)

Você pode ter uma idéia de como isso funciona com o git cat-file -pcomando, que imprime o conteúdo de um hash específico, independentemente do tipo. Por exemplo, para examinar o commit HEAD, você pode executar:

$ 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 a árvore dentro desse commit, você pode cat-file -p:

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

Da mesma forma, se você olhar para os pais, também verá que esses são commits. Uma abreviação para a árvore dentro de um commit como revé rev^{tree}. Portanto, o comando anterior poderia ter sido escrito git cat-file -p HEAD^{tree}. Observe que rev^significa o pai de rev. Quando existem vários pais, rev^1, rev^2, etc. Mais informações estão disponíveis na página do homem rev-parse git .

user3188445
fonte
2

"Commit Hash" é o hash do commit atual. A confirmação à qual a entrada está associada.

"Hash pai" é o hash de qualquer filial (s) pai (s) da qual a confirmação vem.

"Tree hash" é o hash do diretório atual no commit. O hash é igual ao hash que o diretório possui, se visto no diretório pai git ls-files --stage --abbrev.

Referência:

Braiam
fonte
1
o que commit hassignifica no início do seu terceiro parágrafo?
Zen