diff --git a/book/10-git-internals/sections/objects.asc b/book/10-git-internals/sections/objects.asc index fe3094bc..a1670e04 100644 --- a/book/10-git-internals/sections/objects.asc +++ b/book/10-git-internals/sections/objects.asc @@ -4,10 +4,10 @@ Git -- контентно-адресуемая файловая система. Здорово. Что это означает? -А означает это, по сути, что Git -- простое хранилище ключ-значение. -Можно добавить туда любые данные, в ответ будет выдан ключ по которому их можно извлечь обратно. +А означает это, по сути, что Git -- простое хранилище «ключ-значение». +Можно добавить туда любые данные, в ответ будет выдан ключ, по которому их можно извлечь обратно. -В качестве примера, воспользуемся служебной командой `git hash-object`, которая берёт некоторые данные, сохраняет их в виде объекта в каталоге `.git/objects` (_база данных объектов_) и возвращает уникальный ключ, который является ссылкой на созданный объект. +В качестве примера воспользуемся служебной командой `git hash-object`, которая берёт некоторые данные, сохраняет их в виде объекта в каталоге `.git/objects` (_база данных объектов_) и возвращает уникальный ключ, который является ссылкой на созданный объект. Для начала создадим новый Git-репозиторий и убедимся, что каталог `objects` пуст: @@ -34,11 +34,11 @@ d670460b4b4aece5915caf5c68d12f560a9fe3e4 В простейшем случае `git hash-object` берёт переданный контент и возвращает уникальный ключ, который будет использоваться для хранения данных в базе Git. Параметр `-w` указывает команде `git hash-object` не просто вернуть ключ, а ещё и сохранить объект в базе данных. -Последний параметр `--stdin` указывает, что `git hash-object` должна использовать данные, переданные на стандартный потока ввода; в противном случае команда ожидает путь к файлу в качестве аргумента. +Последний параметр `--stdin` указывает, что `git hash-object` должна использовать данные, переданные на стандартный поток ввода; в противном случае команда ожидает путь к файлу в качестве аргумента. Результат выполнения команды -- 40-символьная контрольная сумма. -Это SHA-1 хеш -- контрольная сумма содержимого и заголовка, который будет рассмотрен позднее. -Теперь можно посмотреть как Git хранит ваши данные: +Это SHA-1-хеш -- контрольная сумма содержимого и заголовка, который будет рассмотрен позднее. +Теперь можно посмотреть, как Git хранит ваши данные: [source,console] ---- @@ -63,7 +63,7 @@ test content Теперь вы умеете добавлять данные в Git и извлекать их обратно. То же самое можно делать и с файлами. Например, можно проверсионировать один файл. -Для начала, создадим новый файл и сохраним его в базе данных Git: +Для начала создадим новый файл и сохраним его в базе данных Git: [source,console] ---- @@ -110,8 +110,8 @@ version 2 ---- Однако запоминать хеш для каждой версии неудобно, к тому же теряется имя файла, сохраняется лишь содержимое. -Объекты такого типа называют блобами (англ. blob -- binary large object). -Имея SHA-1 объекта, можно попросить Git показать нам его тип с помощью команды `cat-file -t`: +Объекты такого типа называют блобами (англ. _blob_ -- binary large object). +Имея SHA-1-хеш объекта, можно попросить Git показать нам его тип с помощью команды `cat-file -t`: [source,console] ---- @@ -122,10 +122,10 @@ blob [[r_tree_objects]] ==== Деревья -Следующий тип объектов, который мы рассмотрим, -- деревья -- решают проблему хранения имён файлов, а также позволяют хранить группы файлов вместе. +Следующий тип объектов, который мы рассмотрим -- деревья, -- решают проблему хранения имён файлов, а также позволяют хранить группы файлов вместе. Git хранит данные сходным с файловыми системами UNIX способом, но в немного упрощённом виде. Содержимое хранится в деревьях и блобах, где дерево соответствует каталогу на файловой системе, а блоб более или менее соответствует индексу узла (inode) или содержимому файла. -Дерево может содержать одну или более записей, содержащих SHA-1 хеш, соответствующий блобу или поддереву, права доступа к файлу, тип и имя файла. +Дерево может содержать одну или более записей, содержащих SHA-1-хеш, соответствующий блобу или поддереву, права доступа к файлу, тип и имя файла. Например, дерево последнего коммита в проекте может выглядеть следующим образом: [source,console] @@ -150,7 +150,7 @@ $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 Вы можете столкнуться с различными ошибками при использовании синтаксиса `master^{tree}` в зависимости от того, какую оболочку используете. В Windows CMD символ `^` используется для экранирования, поэтому для исключения ошибок следует использовать двойной символ: `git cat-file -p master^^{tree}`. -В PowerShell параметры, использующие символы {}, должны быть заключены в кавычки: `git cat-file -p 'master^{tree}'`. +В PowerShell параметры, использующие символы `{}`, должны быть заключены в кавычки: `git cat-file -p 'master^{tree}'`. В ZSH символ `^` используется для подстановки, поэтому выражение следует помещать в кавычки: `git cat-file -p "master^{tree}"`. ==== @@ -161,7 +161,7 @@ $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 image::images/data-model-1.png["Упрощённая модель данных Git"] Можно создать дерево самому. -Обычно, Git создаёт дерево путём создания набора объектов из состояния области подготовленных файлов или индекса. +Обычно Git создаёт дерево путём создания набора объектов из состояния области подготовленных файлов или индекса. Поэтому для создания дерева необходимо проиндексировать какие-нибудь файлы. Для создания индекса из одной записи -- первой версии файла `test.txt` -- воспользуемся низкоуровневой командой `git update-index`. Данная команда может искусственно добавить более раннюю версию `test.txt` в новый индекс. @@ -219,8 +219,8 @@ $ git cat-file -p 0155eb4229851634a0f03eb265b69f5a2d56f341 100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt ---- -Обратите внимание, что в данном дереве находятся записи для обоих файлов, а также, что хеш файла `test.txt` это хеш «второй версии» этого файла (`1f7a7a`). -Для интереса, добавим первое дерево как подкаталог текущего. +Обратите внимание, что в данном дереве находятся записи для обоих файлов, а также что хеш файла `test.txt` -- это хеш «второй версии» этого файла (`1f7a7a`). +Для интереса добавим первое дерево как подкаталог текущего. Добавлять деревья в область подготовленных файлов можно с помощью команды `git read-tree`. В нашем случае, чтобы включить уже существующее дерево в индекс и сделать его поддеревом, необходимо использовать опцию `--prefix`: @@ -248,7 +248,7 @@ image::images/data-model-2.png["Структура данных Git для те К тому же у нас нет никакой информации о том, кто, когда и почему сохранил их. Такие данные -- основная информация, хранимая в объекте коммита. -Для создания коммита необходимо вызвать команду `commit-tree` и задать SHA-1 нужного дерева и, если необходимо, родительские коммиты. +Для создания коммита необходимо вызвать команду `commit-tree`, задать SHA-1 нужного дерева и, если необходимо, родительские коммиты. Начнём с создания коммита для самого первого дерева: [source,console] @@ -284,7 +284,7 @@ $ echo 'Third commit' | git commit-tree 3c4e9c -p cac0cab ---- Каждый из созданных объектов коммитов указывает на одно из созданных ранее деревьев состояния проекта. -Вы не поверите, но теперь у нас есть полноценная Git история, которую можно посмотреть командой `git log`, указав хеш последнего коммита: +Вы не поверите, но теперь у нас есть полноценная Git-история, которую можно посмотреть командой `git log`, указав хеш последнего коммита: [source,console] ---- @@ -319,7 +319,7 @@ Date: Fri May 22 18:09:34 2009 -0700 ---- Здорово, правда? -Мы только что выполнили несколько низкоуровневых операций и получили Git репозиторий с историей без единой высокоуровневой команды. +Мы только что выполнили несколько низкоуровневых операций и получили Git-репозиторий с историей без единой высокоуровневой команды. Именно так и работает Git, когда выполняются команды `git add` и `git commit` -- сохраняет блобы для изменённых файлов, обновляет индекс, создаёт деревья и фиксирует изменения в объекте коммита, ссылающемся на дерево верхнего уровня и предшествующие коммиты. Эти три основных вида объектов Git -- блоб, дерево и коммит -- сохраняются в виде отдельных файлов в каталоге `.git/objects`. Вот как сейчас выглядит список объектов в этом каталоге, в комментарии указано чему соответствует каждый из них: @@ -348,7 +348,7 @@ image::images/data-model-3.png["Все объекты в каталоге Git"] Ранее мы упоминали, что вместе с содержимым объекта сохраняется дополнительный заголовок. Давайте посмотрим, как Git хранит объекты на диске. -Мы рассмотрим как происходит сохранение блоб объекта -- в данном случае это будет строка «what is up, doc?» -- в интерактивном режиме на языке Ruby. +Мы рассмотрим как происходит сохранение блоб-объекта -- в данном случае это будет строка «what is up, doc?» -- в интерактивном режиме на языке Ruby. Для запуска интерактивного интерпретатора воспользуйтесь командой `irb`: @@ -359,7 +359,7 @@ $ irb => "what is up, doc?" ---- -Git создаёт заголовок, начинающийся с типа объекта, в данном случае это блоб. +Git создаёт заголовок, начинающийся с типа объекта -- в данном случае это блоб. Далее идут пробел, размер содержимого в байтах и в конце нулевой байт: [source,console] @@ -368,7 +368,7 @@ Git создаёт заголовок, начинающийся с типа об => "blob 16\u0000" ---- -Git объединяет заголовок и оригинальный контент, а затем вычисляет SHA-1 сумму от полученного результата. +Git объединяет заголовок и оригинальный контент, а затем вычисляет SHA-1-сумму от полученного результата. В Ruby значение SHA-1 для строки можно получить, подключив соответствующую библиотеку командой `require` и затем вызвав `Digest::SHA1.hexdigest()`: [source,console]