Raw Git

Здесь мы взглянем на то как манипулировать git на более низком уровне, в случае если вы пожелаете написать инструмент генерирующий новые блобы, деревья, или коммиты искуственным способом. Если вы захотите написать скрипт который использует более низкоуровневые функции git, чтобы проделать что то новое, здесь некоторые инструменты нужные вам.

Создание блобов

Создание блобов в вашем Git репозитории и получение SHA значения несложно. Команда git hash-object это все что вам нужно. Чтобы создать объект блоб из существующего файла, просто выполните ее с параметром '-w' (который говорит ей записать блоб, а не просто вычислить SHA).

$ git hash-object -w myfile.txt
6ff87c4664981e4397625791c8ea3bbb5f2279a3

$ git hash-object -w myfile2.txt
3bb0e8592a41ae3185ee32266c860714980dbed7

В выводе команды вы увидите SHA значение блоба который был создан..

Создание деревьев

Теперь давайте положим вы хотите создать дерево из ваших новых объектов. Команда git mktree делает это просто генерируя новый объект дерево из git ls-tree форматированного вывода. Например, если вы записали следующее в файл под именем '/tmp/tree.txt' :

100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3    file1
100644 blob 3bb0e8592a41ae3185ee32266c860714980dbed7    file2

и затем пропустили это через команду git mktree, Git запишет новое дерево в базу данных объектов и выдаст вам новое sha значение этого дерева.

$ cat /tmp/tree.txt | git mk-tree
f66a66ab6a7bfe86d52a66516ace212efa00fe1f

Затем, мы можем взять это и сделать это поддиректорией еще одного другого дерева, и так далее. Если мы хотим создать новое дерево с этим как поддеревом, мы просто созданим новый файл (/tmp/newtree.txt) с нашим новым SHA как дерево в нем:

100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3    file1-copy
040000 tree f66a66ab6a7bfe86d52a66516ace212efa00fe1f    our_files

и затем выполним git mk-tree снова:

$ cat /tmp/newtree.txt | git mk-tree
5bac6559179bd543a024d6d187692343e2d8ae83

И мы теперь имеем искуственную структуру директорий в Git, которая выглядит следующим образом:

.
|-- file1-copy
`-- our_files
    |-- file1
    `-- file2

1 directory, 3 files

причем это структура никогда в действительности не существовала на диске. Плюс, у нас есть SHA (5bac6559) которое указывает на нее.

Перестроить деревья

Мы также можем проделать манипуляции с объединением деревьев в новую структуру используя файл индекс. Как простейший пример, давайте возьмем дерево которое мы только что создали и сделаем новое дерево которое имеет две копии нашего 5bac6559 дерева в нем используя временный файл индекс. (Вы можете проделать это сбросив переменную окружения GIT_INDEX_FILE или в командной строке)

Первое, мы читаем дерево в наш индекс файл под новым префиксом используя команду git read-tree, и затем запишем содержимое индекса как дерево используя команду git write-tree:

$ export GIT_INDEX_FILE=/tmp/index
$ git read-tree --prefix=copy1/  5bac6559
$ git read-tree --prefix=copy2/  5bac6559
$ git write-tree 
bb2fa6de7625322322382215d9ea78cfe76508c1

$>git ls-tree bb2fa
040000 tree 5bac6559179bd543a024d6d187692343e2d8ae83    copy1
040000 tree 5bac6559179bd543a024d6d187692343e2d8ae83    copy2

Теперь мы видим что мы создали новое дерево просто манипулируя индексом. Вы также можете делать интересные операции слияния и тому подобное во временном индексе. Просмотрите документацию git read-tree чтобы получить больше подробностей.

Создание коммитов

Теперь когда у нас есть SHA дерева, мы можем создать объект коммит которое на него указывает. Мы можем проделать это используя команду git commit-tree. Больщинство данных которые потом войдут в коммит должны быть установленны как переменные окружения, так что вам потребуется установить их:

GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
GIT_AUTHOR_DATE
GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL
GIT_COMMITTER_DATE

Затем вам потребуется записать ваше сообщение-описание коммита в файл или каким либо образом передать эту информацию в команду через STDIN. Затем, вы можете создать ваш коммит основываясь на sha дерева которое есть нас.

$ git commit-tree bb2fa < /tmp/message
a5f85ba5875917319471dfd98dfc636c1dc65650

Если вы хотите определить один или более родителей коммита, просто добавьте sha значения в командную строку вместе с параметром '-p' перед каждым из них. SHA нового объекта коммита будет выведено как результат работы команды..

Обновление ссылки ветки

Теперь у нас есть SHA значение нового объекта коммит, и мы можем обновить ветку чтобы она указывала него если мы так хотим. Давайте скажем что мы хотим обновить нашу ветку 'master' так чтобы она указывала на новый коммит который мы только что создали - мы используем команду git update-ref для этого:

$ git update-ref refs/heads/master a5f85ba5875917319471dfd98dfc636c1dc65650


github logo