Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Git

Глава 6 из книги "Архитектура приложений с открытым исходным кодом", том 2.
Оригинал: Git
Автор: Susan Potter
Перевод: А.Панин

6.5. Репозиторий, данные индексирования и рабочие области

Давайте приступим к непосредственному углубленному исследованию Git на примере локального репозитория для понимания всего лишь нескольких фундаментальных концепций.

Вначале для создания нового инициализированного репозитория Git в нашей локальной файловой системе (при условии использования Unix-подобной операционной системы) мы можем выполнить следующие команды:
$ mkdir testgit
$ cd testgit
$ git init

Теперь в нашем распоряжении пустой, но инициализированный Git-репозиторий, расположенный в директории testgit. Мы можем создавать ветви, добавлять данные, создавать тэги и даже обмениваться данными с другими локальными или удаленными репозиториями Git. Возможен даже обмен данными с репозиториями других типов систем контроля версий при условии использования небольшого набора специальных команд приложения git.

Команда git init создает поддиректорию .git в директории testgit. Давайте рассмотрим ее содержимое:
tree .git/
.git/
|-- HEAD
|-- config
|-- description
|-- hooks
|   |-- applypatch-msg.sample
|   |-- commit-msg.sample
|   |-- post-commit.sample
|   |-- post-receive.sample
|   |-- post-update.sample
|   |-- pre-applypatch.sample
|   |-- pre-commit.sample
|   |-- pre-rebase.sample
|   |-- prepare-commit-msg.sample
|   |-- update.sample
|-- info
|   |-- exclude
|-- objects
|   |-- info
|   |-- pack
|-- refs
    |-- heads
    |-- tags
Находящаяся на верхнем уровне директория .git по умолчанию является поддиректорией корневой рабочей директории testgit. Она содержит несколько различных типов файлов и директорий:
  • Файлы конфигурации (Configuration): файлы .git/config, .git/description и .git/info/exclude участвуют в процессе конфигурации локального репозитория.
  • Директория сценариев (Hooks): директория .git/hooks содержит сценарии, которые могут выполняться в моменты наступления определенных событий в рамках жизненного цикла репозитория.
  • Файл рабочего пространства (Staging Area): файл .git/index (которого пока нет в нашем листинге, представленном выше) будет содержать описание рабочего пространства, соответствующего нашей рабочей директории.
  • База данных объектов (Object Database): директория .git/objects является стандартной базой данных объектов системы Git, которая содержит все данные или указатели на локальные данные. Все объекты являются неизменяемыми с момента создания.
  • Директория ссылок (References): директория .git/refs является стандартным местом для хранения указателей, ссылающихся и на локальные, и на удаленные ветви, а также ветви с тэгами и рабочие ветви. Ссылка является указателем на объект, обычно типа tag или commit. Управление ссылками осуществляется вне базы данных объектов для возможности изменения ссылок в процессе развития репозитория. В особых случаях ссылки могут указывать на другие ссылки, причем примером такого случая является ветвь HEAD.

Директория .git на самом деле является репозиторием. Директория, в которой хранится набор рабочих файлов, является рабочей директорией (working directory), которая обычно является родительской для директории .git (или для репозитория). В том случае, если бы вы создавали удаленный репозиторий Git, в котором не было рабочей директории, вам пришлось бы инициализировать его с помощью команды git init --bare. Эта команда позволила бы просто создать директорию репозитория непосредственно в корневой директории вместо создания репозитория в форме поддиректории рабочей директории с файлами.

Другим очень важным файлом является файл индексирования Git (Git Index): .git/index. Он позволяет создать временное рабочее пространство между локальной рабочей директорией и локальным репозиторием. Индексирование подразумевает хранение данных специфичных изменений в одном файле (или в большем количестве файлов), предназначенных для последующего применения. Даже в том случае, если вы вносите изменения, относящиеся к разным типам функций, эти изменения могут быть внесены в исходный код в рамках единственной операции, сопровождающейся подробным пояснением, позволяющим логически разделить их. Для выборочного сохранения определенных изменений в файле или наборе файлов вы можете использовать команду git add -p.

Данные изменений Git по умолчанию хранятся в единственном файле, расположенном в директории репозитория. Пути к этим трем пространствам хранения данных в рамках дерева директорий могут задаваться с помощью переменных окружения.

Полезно понимать принципы взаимодействий, осуществляющихся между этими тремя пространствами (репозиторием, пространством индексирования и рабочим пространством) в процессе выполнения нескольких основных команд Git:
  • git checkout [ветвь]
    Эта команда приведет к переводу ссылки HEAD-ветви с локального репозитория на текущую ветвь (т.е. refs/heads/master), заполнению файла индексирования данными для выбранной ветви и обновлению содержимого рабочей директории для соответствия данным выбранной ветви.
  • git add [файлы]
    Эта команда приведет к созданию перекрестных ссылок с использованием контрольных сумм между файлами, описанными в файле индексирования для того, чтобы установить необходимость обновления файла индексирования для измененных файлов в соответствии с версией рабочей директории. В директории Git (или репозитории) ничего не изменится.
Давайте установим более конкретное значение этих утверждений, исследовав содержимое файлов в директории .git (или репозитории).
$ GIT_DIR=$PWD/.git
$ cat $GIT_DIR/HEAD

ref: refs/heads/master

$ MY_CURRENT_BRANCH=$(cat .git/HEAD | sed 's/ref: //g')
$ cat $GIT_DIR/$MY_CURRENT_BRANCH

cat: .git/refs/heads/master: No such file or directory

Мы столкнулись с ошибкой из-за того, что перед добавлением любых данных в репозиторий Git не задается никаких ветвей кроме стандартной для Git ветви с именем master, причем самой ветви может и не существовать.

Теперь, когда мы снова попытаемся добавить данные, ветвь master будет создана по умолчанию для выполнения данной операции. Давайте выполним операцию (продолжая работу в той же командной оболочке для сохранения истории команд и контекста):
$ git commit -m "Initial empty commit" --allow-empty
$ git branch

* master

$ cat $GIT_DIR/$MY_CURRENT_BRANCH

3bce5b130b17b7ce2f98d17b2998e32b1bc29d68

$ git cat-file -p $(cat $GIT_DIR/$MY_CURRENT_BRANCH)

Здесь мы наблюдаем представление данных в рамках базы данных объектов Git.


Следующий раздел: База данных объектов