Скотт Чакон - Pro Git
- Название:Pro Git
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Скотт Чакон - Pro Git краткое содержание
В книге рассматриваются следующие темы: основы Git;
ветвление в Git;
Git на сервере;
распределённый Git;
GitHub;
инструменты Git;
настройка Git;
Git и другие системы контроля версий.
Pro Git - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
$find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
Мы видим новый файл в директории objects. Это и есть начальное внутреннее представление данных в Git — один файл на единицу хранения с именем, являющимся контрольной суммой содержимого и заголовка. Первые два символа SHA-1 определяют поддиректорию файла внутри objects, остальные 38 — собственно, имя.
Получить обратно содержимое объекта можно командой cat-file. Она подобна швейцарскому ножу для проверки объектов в Git. Ключ -p означает автоматическое определение типа содержимого и вывод содержимого на печать в удобном виде:
$git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content
Теперь вы умеете добавлять данные в Git и извлекать их обратно. То же самое можно делать и с файлами. Например, можно проверсионировать один файл. Для начала, создадим новый файл и сохраним его в базе данных Git:
$echo 'version 1' > test.txt
$git hash-object -w test.txt
83baae61804e65cc73a7201a7252750c76066a30
Теперь изменим файл и сохраним его в базе ещё раз:
$echo 'version 2' > test.txt
$git hash-object -w test.txt
1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
Теперь в базе содержатся две версии файла, а также самый первый сохранённый объект:
$find .git/objects -type f
.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
Теперь можно откатить файл к его первой версии:
$git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt
$cat test.txt
version 1
или ко второй:
$git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt
$cat test.txt
version 2
Однако запоминать хеш для каждой версии неудобно, к тому же теряется имя файла, сохраняется лишь содержимое. Объекты такого типа называют блобами (англ. blob — binary large object). Имея SHA-1 объекта, можно попросить Git показать нам его тип с помощью команды cat-file -t:
$git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
blob
Деревья
Следующий тип объектов, который мы рассмотрим, — деревья — решают проблему хранения имён файлов, а также позволяют хранить группы файлов вместе. Git хранит данные сходным с файловыми системами UNIX способом, но в немного упрощённом виде. Содержимое хранится в деревьях и блобах, где дерево соответствует директории на файловой системе, а блоб более или менее соответствует inode или содержимому файла. Дерево может содержать одну или более записей, содержащих SHA-1 хеш, соответствующий блобу или поддереву, права доступа к файлу, тип и имя файла. Например, дерево последнего коммита в проекте может выглядеть следующим образом:
$git cat-file -p master^{tree}
100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
Запись master^{tree} указывает на дерево, соответствующее последнему коммиту ветки master. Обратите внимание, что поддиректория lib — не блоб, а указатель на другое дерево:
$git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rb
Концептуально, данные хранятся в Git примерно так:
Рисунок 1. Упрощённая модель данных Git.
Можно создать дерево самому. Обычно Git создаёт деревья на основе индекса, затем сохраняя их в БД. Поэтому для создания дерева необходимо проиндексировать какие-нибудь файлы. Для создания индекса из одной записи — первой версии файла test.txt — воспользуемся низкоуровневой командой update-index. Данная команда может искусственно добавить более раннюю версию test.txt в новый индекс. Необходимо передать опции --add, т.к. файл ещё не существует в индексе (да и самого индекса ещё нет), и --cacheinfo, т.к. добавляемого файла нет в рабочей директории, но он есть в базе данных. Также необходимо передать права доступа, хеш и имя файла:
$git update-index --add --cacheinfo 100644 \
83baae61804e65cc73a7201a7252750c76066a30 test.txt
В данном случае права доступа — 100644, означают обычный файл. Другие возможные варианты: 100755 — исполняемый файл, 120000 — символическая ссылка. Права доступа в Git сделаны по аналогии с режимами доступа в UNIX, но они гораздо менее гибки: данные три режима — единственные доступные для файлов (блобов) в Git (хотя существуют и другие режимы, используемые для директорий и дочерних модулей).
Теперь можно воспользоваться командой write-tree для сохранения индекса в виде дерева. Здесь опция -w не требуется — вызов write-tree автоматически создаёт дерево из индекса, если такого дерева ещё не существует:
$git write-tree
d8329fc1cc938780ffdd9f94e0d364e0ea74f579
$git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
100644 blob 83baae61804e65cc73a7201a7252750c76066a30 test.txt
Можно проверить, что мы действительно создали дерево:
$git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579
tree
Давайте создадим новое дерево со второй версией файла test.txt и ещё одним файлом:
$echo 'new file' > new.txt
$git update-index test.txt
$git update-index --add new.txt
Теперь в индексе содержится новая версия файла test.txt и новый файл new.txt. Зафиксируем изменения, сохранив состояние индекса в новое дерево, и посмотрим, что из этого вышло:
$git write-tree
0155eb4229851634a0f03eb265b69f5a2d56f341
$git cat-file -p 0155eb4229851634a0f03eb265b69f5a2d56f341
100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
Обратите внимание, что в данном дереве находятся записи для обоих файлов, а также, что хеш файла test.txt это хеш "второй версии" этого файла (1f7a7a). Для интереса, добавим первое дерево как поддиректорию текущего. Вычитать дерево в индекс можно командой read-tree. В нашем случае, чтобы прочитать уже существующее дерево в индекс и сделать его поддеревом, необходимо использовать опцию --prefix:
$git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579
$git write-tree
3c4e9cd789d88d8d89c1073707c3585e41b0e614
$git cat-file -p 3c4e9cd789d88d8d89c1073707c3585e41b0e614
040000 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579 bak
100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt
100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt
Если бы вы сейчас вычитали только что сохранённое дерево в рабочую директорию, вы бы увидели два файла в корне рабочей директории и поддиректорию bak с первой версией файла test.txt. Представьте, что данные хранятся в Git следующим образом:
Рисунок 2. Структура данных Git для последнего дерева.
Commit Objects
У вас есть три дерева, соответствующих разным состояниям проекта, но предыдущая проблема с необходимостью запоминать все три значения SHA-1, чтобы иметь возможность восстановить какое-либо из этих состояний, ещё не решена. К тому же у нас нет никакой информации о том, кто, когда и почему сохранил их. Такие данные — основная информация, хранимая в коммите.
Для создания коммита необходимо вызвать команду commit-tree и задать SHA-1 нужного дерева и, если необходимо, родительские коммиты. Для начала создадим коммит для самого первого дерева:
Читать дальшеИнтервал:
Закладка: