git add
копирует файл из рабочего дерева в индекс.Этот процесс требует, чтобы файл существовал;git add
будет использовать это же имя в индексе.
Технически, то, что действительно делает git add
, состоит из двух шагов:
Он должен создать или найти blob объект в базе данных репозитория, который содержит содержимое файла.Если файл пуст, объект, который входит в базу данных или уже находится в базе данных, имеет этот хэш:
$ git hash-object -t blob --stdin < /dev/null
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
Вы можете эмулировать это, запустив git hash-object
с флагом -w
, который говорит Git записать объект в базу данных при необходимости, а затем возвращает вам хэш-идентификатор, представляющий это содержимое.
Теперь, когда объект находится в базе данных (заново записывается, еслинеобходимо) и у нас есть его хэш-идентификатор, git add
продолжает обновлять индекс.Это обновление состоит из удаления любых записей более высокого уровня с тем же именем и записи в запись нулевого уровня.Содержимое записи - это требуемый режим файла - либо 100644
, если файл должен быть помечен для чтения / записи, либо 100755
, если он должен быть помечен для чтения / записи / выполнения, номер этапа (ноль), идентификатор хэша BLOB-объекта и путь (представленный в виде строки UTF-8).
Второй шаг можно выполнить с помощью git update-info
, либо с помощью --index-info
(который читает из стандартного ввода) или --cacheinfo
(который ограничен записью записей нулевой ступени, но это то, что вы хотите в любом случае).Подробнее см. документацию git update-index
.
. Проблема с этим вместо touch file; git add file
заключается в том, что, если вы уже не знаете идентификатор хеш-кода для содержимого, и , что этот хэш-идентификатор на самом деле уже находится в базе данных Git, он все еще принимает две команды: git hash-object -w ...
и git update-index ...
.И в этом случае вы могли бы также использовать вместо этого простые команды.
(Обратите внимание, что хотя все хранилища имеют пустое дерево , они не имеют пустая капля изначально.)