Какие сантехнические команды достигают того же уровня, что и git add?

Я хотел бы лучше понять git-сантехнику, узнав, что на самом деле происходит при входе

git add $DIRECTORY

а также

git add $FILE

Как это работает?

Грубая идея может быть получена, прочитав секцию git inners progit.

  • Если $DIRECTORYэто каталог, что-то вроде find $DIRECTORY -type f -exec git add {} \; т.е. рекурсивное добавление всех файлов в$DIRECTORY, Затем,git add $FILENAMEприменяется для каждого файла.
  • Проверка против.gitignore(и его "начальство")
  • Проверка против.gitattributesработаетcleanфильтр, если применимо
  • git hash-object -w cleanсодержание

И затем, индекс получает обновления как-то, что включает в себя git mktree. Но что именно там происходит? Содержит ли дерево для каталога только добавленные файлы или все файлы, которые были ранее зафиксированы? А что будет дальше?

1 ответ

Решение

git add не имеет ни одной эквивалентной команды сантехника, но, вероятно, самая близкая git update-index, Описание ProGit верно:

  1. Замените каждый каталог списком содержимого каталога. Результатом является список файлов, указанных addс некоторой особой обработкой случаев для файлов, о которых сейчас известно, что они не находятся в каталоге (то есть удалены), и для файлов со специальными индексными состояниями (--assume-unchanged а также --skip-worktree). Другими словами, этот шаг также обращается к текущему индексу.

  2. Проверить на неподключенную, но игнорируемую (через .gitignore) файлы и исключить их из списка (с предупреждением), если не указано иное -f / --force,

    (Примечание: я не проверял это в подкаталогах, и возможно, что -f не будет применяться к записи подкаталога, выбранной при рекурсивном сканировании, но только к именам, фактически указанным в командной строке. В этом случае шаг 2 должен быть объединен с шагом 1, чтобы имена не добавлялись, если мы собираемся игнорировать их даже при -f.)

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

  4. использование git update-index --add --remove --replace чтобы получить измененные файлы, записанные в хранилище, с обновленными записями их индексов, включая обновления режима. (Для файлов, очищенных на шаге 3, вам придется использовать отдельный git hash-object -w, как вы предложили, и --index-info вместо --add --remove --replace.)

git mktree команда вообще не входит в этот процесс, так как сам индекс представляет собой просто плоский файл, использующий плохо документированный формат (или, точнее, один из нескольких форматов; см. --index-version).

Индекс допускает до четырех записей для каждого имени файла, которые называются этапами: этап 0 является обычной записью в кэш, а этапы с 1 по 3 предназначены для конфликтующих объединений. Есть несколько специальных битов для маркировки удаленных файлов, или --assume-unchanged, --skip-worktree, --intent-to-addи некоторые специальные внутренние флаги использования, и, хотя Git не хранит каталоги, есть записи индекса для каталогов (которые позволяют Git просматривать ctime поле каталога, которое затем позволяет Git быстро пропускать неизмененные каталоги, при условии, что он может доверять ОС для поддержки этого).

git mktree Команда вступает в действие только при преобразовании индекса в серию древовидных объектов. Git должен создать одно дерево для каждого подкаталога в индексе, плюс одно дерево верхнего уровня, представляющее общий индекс. (Подпроекты, если таковые существуют, уже включены в индекс как записи "gitlink", как они выглядят в любом дереве, в котором они содержатся.)

Другие вопросы по тегам