В чем разница между `Commit hash`,` Parent Hash` и `Tree hash` в git?

12

Сегодня я изучаю некоторые базовые знания по git, читая этот документ онлайн:

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

И в этой главе я начинаю учиться использовать, git log --pretty=format:" "чтобы показать информацию журнала в моем вкусе.

Но кое-как, я видел в таблице форматирования два похожих варианта, %Hдля Commit Hash, %Pдля Parent Hashи %Tдля Tree Hash.

Я экспериментировал с ними в командной строке, оказалось, что все они имеют хеш-значения одинаковой длины с разным значением.

Я гуглил и переполнялся стеком, никаких явных намеков пока нет.

У меня есть идея об этом Hash value, это контрольная сумма этого git commit.

Но что делает Parent Hashи Tree hashделает?

  • PS: А теперь у меня есть некоторые идеи, Parent Hashозначает ли это хэш-значение прямого происхождения ветви?
Zen
источник

Ответы:

7

Родительские хеши:

$ 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

Вы можете видеть commit4, а commit3 является родителем commit5 , commit2 является родителем commit3 и commit4 , commit1 является родителем commit2 .

Хэш дерева:

$ 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

Функция команды: Pretty-печатать содержимое в <object>зависимости от его типа.

git cat-file -p 

В git весь контент хранится в виде объектов дерева и больших двоичных объектов, причем деревья соответствуют записям в каталоге UNIX, а большие двоичные объекты более или менее соответствуют объектам inode или содержимому файла. Один объект дерева содержит одну или несколько записей дерева, каждая из которых содержит указатель SHA-1 на большой двоичный объект или поддерево со связанным с ним режимом, типом и именем файла. Git обычно создает дерево, беря состояние вашей промежуточной области или индекса и записывая из него серию древовидных объектов. Объекты коммитов содержат информацию о том, кто сохранил объект дерева, когда он был сохранен или почему он был сохранен. Это основная информация, которую объект фиксации хранит для вас.

Заключение:

Зафиксируйте хеш, родительский хеш, хеш дерева - все это SHA-1. Хэш коммитов и родительский хеш идентичны, за исключением того, что родительский хеш имеет дочерний. Хэш дерева представляет собой объект дерева. Хеш коммита и родительский хеш представляют объект коммита.

Справка:

  1. Git Internals - Git Объекты

  2. git-cat-file - предоставляет информацию о содержимом, типе и размере для объектов репозитория.

linjie
источник
4

Дерево представляет собой иерархическую совокупность файлов и каталогов, а не привязаны к какой - либо конкретной точке в истории. Например, если вы создаете файл, а затем удаляете файл (без других промежуточных коммитов), вы получите то же дерево, с которого вы начали.

Фиксации является точкой в истории вашего проекта. Коммит задает дерево, но также содержит другую информацию, такую ​​как автор / коммиттер и время, сообщение о коммите (в котором автор описывает, что изменилось) и, что наиболее важно, ноль или более родителей, которые являются предыдущим состоянием хранилища. (Ваш первый коммит имеет нулевых родителей. Большинство коммитов после этого имеют одного родителя во время линейного развития и более одного в случае слияния.)

Вы можете понять, как это работает с git cat-file -pкомандой, которая печатает содержимое определенного хэша, независимо от его типа. Например, чтобы посмотреть коммит HEAD, вы можете запустить:

$ 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

Чтобы увидеть дерево внутри этого коммита, вы можете cat-file -pэто дерево:

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

Точно так же, если вы посмотрите на родителей, вы увидите, что это тоже коммиты. Сокращение для дерева внутри коммита, как revесть rev^{tree}. Так что предыдущая команда могла быть написана git cat-file -p HEAD^{tree}. Обратите внимание, что rev^обозначает родителя rev. При наличии нескольких родителей, rev^1, rev^2и т.д. Более подробная информация доступна в Rev-синтаксического анализа страницы человека мерзавца .

user3188445
источник
2

«Commit Hash» - это хэш текущего коммита. Фиксация, с которой связана запись.

«Родительский хэш» - это хэш для любой родительской ветви (веток), из которой происходит принятие.

«Хэш дерева» - это хэш текущего каталога в коммите. Хеш равен хешу, который имеет каталог, если смотреть из родительского каталога с git ls-files --stage --abbrev.

Справка:

Braiam
источник
1
что commit hasзначит в начале вашего третьего абзаца?
Zen