Дерево коммитов#
Хранилище – это база данных, содержащая коммиты. Коммит – это запись с информацией что, когда, кем и почему было изменено. Коммит основывается на другом коммите, который задает состояние рабочей копии. Отдельный коммит не несет полного состояния рабочей копии. Рабочую копию можно восстановить, только если применить все изменения предыдущих коммитов, начиная с начального.
Дочерний коммит ссылается на родительский, но родительский не содержит ссылки на дочерний. Почему так происходит? Содержимое коммита не может быть изменено в последующем и это контролируется хеш-суммой объекта, которая одновременно является идентификатором коммита. Поэтому ссылки на родителя добавляются при формировании дочернего. В результате мы получаем структуру данных “односвязный список”.
Чтобы извлечь рабочую копию из указанного коммита, система спускается по ссылкам на начальный коммит и, поднимаясь в обратном направлении, применяет изменения в коммитах к рабочей копии. Для такого процесса удобен стек, заполняемый коммитами при движении по списку и дающая подъем при извлечении из стека элементов. Те коммиты, к которым можно добраться, следуя по указателям от заданного, называются достижимыми.
Структура “односвязный список” превращается в “дерево” при одновременной работе над проектом нескольких участников и совмещении их “списков”.
Заметим, что получившаяся структура не похожа на классическое дерево.
В классическом дереве можно от корня достичь любого листа.
Здесь связи ориентированы в обратном порядке: дочерний узел ссылается на родительский.
Для достижения всех коммитов, нужно спускаться по дереву от трех из них: 654, dc1, 31a.
Мы должны хранить указатели на листовые узлы.
В Git указатели на коммиты – это ветки и теги. В отличие от тегов, ветки – это перемещаемые указатели.
Указатель HEAD показывает на коммит, откуда была извлечена рабочая копия.
При создании нового коммита родительским будет выбран тот, на который указывает HEAD.
По правильному, HEAD указывает на ветку.