Внутреннее устройство 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).
Полезные команды для "рентгена" репозитория
| Задача | Команда |
|---|---|
Размер .git | du -sh .git (Linux/macOS) |
| Список pack-файлов | ls .git/objects/pack/ |
| Где лежит ветка | cat .git/refs/heads/main |
| История перемещений HEAD | git reflog |
| Проверка целостности | git fsck |
| Сборка мусора (осторожно) | git gc — не сразу после ошибки, сначала reflog (Опасные скрипты) |
Флаги команд и уровни git config — Настройка и параметры Git.