Как Работает Git. Начало
Определение Git в Википедии - распределённая система контроля версий. То есть мало того, что Git делает то, что делают другие системы контроля версий (такие как Subversion), он делает это распределённым способом.
Это довольно сложно понять сразу, поэтому уберём один слой – распределённость. Представим, что в мире есть только один компьютер и на нём есть репозиторий. Таким образом, Git становится просто системой контроля версий. Однако это тоже сложное понятие. Оно включает в себя такие вещи, как история, ветки, слияния… Упрощаем дальше. Забудем про ветки, историю и т.п. Теперь это можно назвать примитивным трекером контента (stupid content tracker – определение Git из документации). Потому что это всё, что он делает - отслеживает контент, файлы или каталоги. Но давайте забудем и об отслеживании контента. Посмотрим на самую суть, основную идею. И на самом деле Git – это просто карта, которая сопоставляет ключи со значениями.
Значения - это просто любая последовательность байт, например, содержимое текстового или даже двоичного файла. Для ключа Git вычисляет хэш значения с помощью алгоритма SHA‑1. У каждого объекта в репозитории есть собственный хэш-ключ. SHA‑1 представляет собой последовательность из 40 шестнадцатеричных цифр, например,
239982efa3b9bb5cf84e1b8a9f188025432e789e. Для получения хэша значения используется команда git hash-object.Хранение
Теперь посмотрите в папку с любым репозиторием Git. В ней есть скрытая папка
.git, которая и хранит репозиторий. Зайдите в папку .git/objects. Пока не обращайте внимания на папки init и pack. Заметьте, что остальные папки содержат первые 2 символа хэша, а файлы внутри этих папок названы оставшимися 38 символами. Для объекта выше это будет папка 23, файл 9982efa3b9bb5cf84e1b8a9f188025432e789e. Этот файл содержит сжатое значение. Значение можно посмотреть с помощью команды git cat-file, передав ей хэш. Параметр -t выдаст нам тип объекта (в данном случае blob), а параметр -p распакует и выдаст содержимое файла.И точно так же хранятся все коммиты. Коммит – это просто текстовый файл, хранящийся в репозитории. Его так же можно посмотреть через
git cat-file. Только, если передать параметр -t, то результатом будет commit. git cat-file 1177e23 -pПомимо данных об авторе, времени и сообщении лога, коммит содержит хэш ещё одного объекта типа tree. В Git
tree be4d42cd6ecc95e9fa5bc3e029bf28bb263104c0
author S.Benzenko <…> 1606106642 +0300
committer S.Benzenko <…> 1606106642 +0300
Initial commit
blob представляет файл, а tree - папку. Коммит указывает на корень проекта. Так же, как и всё остальное, tree – это текстовый файл, который содержит список хэшей файлов и папок, их имена, а также цифровое представление прав доступа к ним. git cat-file be4d42cd -pПри этом Git хранит только содержимое файла. Если несколько файлов имеют одинаковое содержимое (т.е. одинаковый хэш), реально храниться в репозитории содержимое будет только один раз в объекте
100644 tree 3ee7d56f… folder1
100644 blob 239982ef… file1.txt
blob с этим хэшем, но несколько объектов tree будут ссылаться этот объект blob и хранить разные имена этих файлов. Например, посмотрим содержимое папки folder1:git cat-file 3ee7d56 -pЗдесь два файла
100644 blob 361ad437… README.md
100644 blob 239982ef… samefile1.txt
file1.txt и samefile1.txt имеют одинаковое содержимое, поэтому хранятся, как один blob объект с хэшем 239982ef…. Имена файлов хранятся в объектах tree be4d42cd (корень) и 3ee7d56 (папка folder1).Продолжение следует…
Источник: https://app.pluralsight.com/library/courses/how-git-works