Git ветки: повторное использование блобов и HEAD

Рассмотрим изменения в репозитории Git после принудительного коммита первого коммита в ветке br1.

Анализ коммита и объекта дерева

Коммит, созданный в ветке br1, содержит указатель на объект дерева и его SHA-хеш. Проанализируем содержимое объекта дерева (git cat-file -p <SHA-хеш>). В нём видим ссылку на один блоб, имя файла для этого блоба и его SHA-хеш.

Этот SHA-хеш (например, b7ae…) встречался ранее, в самом первом коммите проекта. В папке objects репозитория Git созданы две папки (например, 0b и 28). В папке 0b находится исследуемый объект (хеш начинается с 0b 7a…). В папке 28 — объект коммита (хеш начинается с 285b…). Git создал только два объекта, а не три.

Проверим файл с SHA-хешем b7ae… (git cat-file -p <SHA-хеш>). Его тип (git cat-file -t <SHA-хеш>) — блоб. Содержимое блоба (git cat-file -p <SHA-хеш>) — строка «hello git».

Повторное использование блобов

Это демонстрирует повторное использование Git существующих блобов, даже если имя файла отличается. Создан новый файл (file4.txt) с тем же содержимым, что и file1.txt.

Диаграмма (не представлена в тексте) показала бы все созданные коммиты, деревья и блобы. Первый коммит в ветке br1 указывает на объект дерева, который, в свою очередь, ссылается на file4.txt. Содержимое file4.txt идентично содержимому file1.txt, поэтому Git повторно использовал существующий блоб. Имена файлов хранятся в деревьях, нет необходимости создавать новые блобы с одинаковым содержимым. Каждый файл в папке objects имеет имя, основанное на SHA-1 хеше содержимого блоба. Если содержимое одинаковое, SHA-хеш тоже одинаковый. В нашем случае, SHA-хеш блоба (b7ae…) совпадает.

Проверка первого коммита (git checkout <SHA-хеш>) показывает тот же SHA-хеш (b7ae…) в дереве. Содержимое file1.txt — «hello git». Объект коммита содержит указатель на объект дерева, который ссылается на два блоба (file1.txt и file2.txt), имеющих тот же SHA-хеш, что и file4.txt в последнем коммите.

В новой ветке br1, после первого коммита, Git создал объект коммита и объект дерева, но повторно использовал существующий объект блоба, поскольку содержимое file4.txt совпадает с содержимым file1.txt. Теперь есть две ветки, между которыми можно легко переключаться и создавать разные коммиты.

Переключение на ветку br1 (git checkout br1) показывает только file4.txt. Переключение на ветку master (git checkout master) показывает отсутствие файлов, поскольку в последнем коммите в master все файлы были удалены.

Мы показали создание новых веток, создание коммитов в ветках, а также переключение между ветками и коммитами.

Что будем искать? Например,программа