Как git управляет каталогами
2 ответа
Я знаю, что Git не увидит пустой каталог...
Это не совсем верно. Git увидит это отлично, просто не сохранит.
но кто-то может дать ссылку на некоторую документацию о том, как именно это реализовано.
Хорошее программное обеспечение обычно пытается скрыть детали реализации, что говорит о том, что Git не очень хорош,:-), но в этом случае детали реализации действительно довольно хорошо скрыты. Внутренняя документация Git находится здесь, с одним скелетом api-in-core-index.txt, который последний раз обновлялся 9 лет назад (!), И более поздним index-format.txt. В любом случае, отслеживание связано с индексом Git, который имеет несколько имен: "индекс", "промежуточная область" и "кэш".
Речь идет не только о пустых папках. Если я добавляю файл в новую папку, но не добавляю его в область подготовки, Git фактически видит папку, но не файл.
Это тоже не совсем верно. Попробуйте запустить git status -uall
(или, что эквивалентно, git status --untracked-files=all
). 1 Здесь происходит то, что git status
Команда обычно суммирует неотслеживаемые файлы с помощью простого правила: если каталог с именем dir
существует, и некоторые неотслеживаемые файлы были найдены в dir
но внутри не было найдено ни одного отслеженного файла dir
Гит просто печатает dir/
вместо того, чтобы перечислять каждый файл в dir
,
Если вы используете -uno
(или же --untracked-files=no
), Git даже не ищет неотслеживаемые файлы, что экономит время. В большом хранилище (десятки тысяч каталогов, сотни тысяч или даже миллионы файлов) это может иметь значение между git status
занимая менее одной секунды, и git status
займет много секунд.
Поиск всех неотслеживаемых файлов требует сравнения фактического рабочего дерева с кэшированной версией рабочего дерева, хранящейся в индексе. В обычном (суммирующем) режиме Git может иногда использовать свой кэш, чтобы избежать не только перечисления файлов внутри dir
, но даже заглядывая внутрь dir
, что также экономит время.
Конечно, вообще не искать неотслеживаемый файл означает, что Git никогда не напомнит вам git add
такие файлы. Таким образом, режим по умолчанию (суммирование) подразумевается как компромисс, как с точки зрения скорости работы ("Если dir
содержит любые файлы 2 в себе или через подкаталоги, но мы уже не знаем файлов внутри dir
отслеживаются, не нужно выполнять более детальное сканирование файлов ") и удобство использования (" нет необходимости спамить список с 19 365 именами файлов в пределах dir
когда мы можем просто сказать dir/
").
1 По умолчанию, если вы не укажете опции, -unormal
, но если указать -u
, это означает -uall
, Вы также можете установить status.showUntrackedFiles
переменная конфигурации для изменения по умолчанию.
2 Тестирование это ("делает dir
или его подкаталоги содержат любые обычные файлы ") отчасти зависит от поддержки d_type
поле в readdir
"s dirent
данные, которые не требуются POSIX, но являются общими (они, безусловно, встречаются во всех современных вариантах Unix). Последние версии Git также имеют расширение "неотслеживаемый кеш" для формата индекса, описанного в той же технической документации, которое позволяет Git пропускать чтение неотслеживаемых каталогов, если их stat
данные не изменились, используя mtime
поле stat
структура.
Существует два уровня того, что происходит: что происходит под капотом (сантехника) и что вы на самом деле видите (фарфор).
Чтобы узнать все о слесарном слое, я рекомендую проверить этот раздел Pro Git. Короче говоря, каталог хранится как tree
объект с содержанием вроде
100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
Первый столбец для разрешений, второй столбец для того, является ли это blob
(файл) или tree
(другой каталог), третий столбец для SHA-1 объекта, а последний столбец - имя файла.
Хотя на водопроводной стороне нет ничего, что мешало бы вам поставить пустую tree
объект в коммите, это может вызвать проблемы позже. Если вы хотите добиться аналогичного эффекта, вы можете поместить файл в каталог. Если вы хотите, чтобы каталог оставался пустым, вы можете использовать это решение; если вам все равно, если люди выложат файлы позже, это может быть README
или пустой .gitignore
,