Перейти к основному содержимому

Внутреннее устройство Git

Разработчику Архитектору Инженеру

Понимание папки .git помогает не бояться "магии" команд — вы видите, где лежит история, почему git reset иногда откатывает только индекс, а reflog — ещё способ найти "потерянный" коммит. Практика команд — Архитектура системы контроля версий Git, протоколы и packfile — Особенности работы с репозиториями в Git, опасные операции — Опасные скрипты.

С чего начать новичку

Сначала освойте цикл status → add → commit → push в 4.13

возвращайтесь сюда за внутренней моделью объектов.


Внутренности .git и алиасы

Папка .git

Play ITЗагрузка интерактивного демо…

Когда вы инициализируете репозиторий с помощью git init, создаётся скрытая папка .git. Это всё, что Git использует для отслеживания изменений. Рабочие файлы проекта лежат рядом с .git; при clone копируется и .git, и снимок файлов на выбранную ветку.

Файл/папкаОписание
HEADУказывает на текущую ветку или коммит (если detached). Обычно содержит ссылку на refs/heads/<branch>. Например, refs/heads/main содержит SHA-1 последнего коммита на ветке main.
configКонфигурационный файл локального репозитория (имя пользователя, remote-репозитории и т.д.). Пример содержимого: [user] name = John Doe email = john@example.com [remote "origin"] url = https://github.com/john/repo.git fetch = +refs/heads/*:refs/remotes/origin/*
descriptionОписание репозитория (используется в GUI-инструментах)
hooks/Каталог для скриптов, выполняемых при определённых событиях Git (например, pre-commit, post-merge). Содержимое проверяйте после клонирования чужого репо — см. Опасные скрипты
indexИндекс (staging area) — список файлов, подготовленных к включению в следующий коммит
info/Содержит служебную информацию, например, исключения для отображения в git log
logs/Журнал изменений ссылок (refs) и HEAD — основа reflog
objects/Хранение всех данных репозитория: коммитов, деревьев (trees), блобов (файлов) в сжатом виде по хешам SHA-1. Файлы размещаются в подкаталогах, имена которых соответствуют первым двум символам хеша, например: objects/ab/cdef1234567890...
refs/Каталог ссылок на коммиты: ветки (refs/heads/), теги (refs/tags/), удалённые ветки (refs/remotes/)

Объектная модель Git

Git опирается на объектную модель. Четыре типа:

ТипЧто хранитКак появляется
blobСодержимое одного файлаgit add кладёт blob в objects/
treeКаталог: имена, режимы, ссылки на blob/treeСобирается при коммите
commitУказатель на tree, родитель(и), автор, сообщениеgit commit
tagУказатель на commit (легковесный или аннотированный)git tag

Цепочка для одного коммита:

commit → tree (корень проекта) → tree (папка src/) → blob (main.py)

Посмотреть объект в терминале (учебный репозиторий):

git rev-parse HEAD
git cat-file -t HEAD # commit
git cat-file -p HEAD # метаданные коммита
git ls-tree -r HEAD --name-only

Хеш объекта зависит только от содержимого и типа. Два одинаковых файла в разных папках дадут один blob — экономия места; переименование без изменения текста часто меняет только tree.

Учебный эксперимент (в пустой папке):

git init example
cd example
echo "hello" > file.txt
git add file.txt
git commit -m "first"

# hash blob
git hash-object file.txt
git cat-file -p HEAD^{tree}
git rev-parse HEAD
ls .git/objects/*/*

После второго коммита с тем же текстом в другом файле git count-objects -v покажет переиспользование blob.

Индекс и три состояния

Рабочий каталог — файлы на диске.

Индекс (.git/index) — что войдёт в следующий коммит.

HEAD — последний зафиксированный снимок. git diff сравнивает рабочий каталог с индексом; git diff --staged — индекс с HEAD.

Упаковка множества объектов в packfile, дельты и сеть — в Особенности работы с репозиториями в Git.


Алиасы

Git позволяет создавать алиасы для команд — чтобы упростить и ускорить работу.

git config --global alias.<alias-name> "<command>"

Примеры:

Код ITЗагрузка примера кода…

Алиасы хранятся в глобальном конфиге Git ~/.gitconfig или git config --global --edit. Пример содержимого:

[alias]
st = status
co = checkout
br = branch
ci = commit
undo = reset HEAD~1
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

Алиасы можно использовать для сложных сочетаний. Можно добавлять даже собственные shell-команды через ! (например, git config --global alias.aliases '!git config --get-regexp alias').

Алиас ≠ безопасная команда

git undo и похожие сокращения вызывают reset без лишних вопросов.

Перед настройкой алиасов — Опасные скрипты (Git, reflog).


Полезные команды для "рентгена" репозитория

ЗадачаКоманда
Размер .gitdu -sh .git (Linux/macOS)
Список pack-файловls .git/objects/pack/
Где лежит веткаcat .git/refs/heads/main
История перемещений HEADgit reflog
Проверка целостностиgit fsck
Сборка мусора (осторожно)git gc — не сразу после ошибки, сначала reflog (Опасные скрипты)

Флаги команд и уровни git configНастройка и параметры Git.