Действительно ли статус git вычисляет и проверяет SHA для содержимого всего рабочего каталога? - PullRequest
0 голосов
/ 07 февраля 2020

Когда я выполняю вычисление SHA1 для некоторого файла, используя для этого какой-то инструмент (например, HashCal c), это занимает некоторое время, если файл немного больше (например, 1 ГБ и более). Но если я запускаю статус git поверх хранилища размером 5 ГБ или более, создается впечатление, что статус git проверяет файлы на наличие изменений не более чем на несколько секунд.

Теперь вопрос в том, действительно ли статус git вычисляет и проверяет SHA файлов, или он просто сравнивает время и дату последнего изменения файлов с записями в индексе?

1 Ответ

0 голосов
/ 07 февраля 2020

Команда git status не вычисляет хэши. 1

Что делает git status:

  • выводит информацию о текущей ветви, который включает чтение файла HEAD и, возможно, нескольких небольших файлов;
  • сравнивает (как в git diff --name-status) каждый файл в HEAD коммите с каждым файлом в индексе; и
  • сравнить (как в git diff --name-status) каждый файл в индексе с каждым файлом в вашем рабочем дереве.

Выходной раздел, где git status показывает изменения быть зафиксированными и изменения, не подготовленные для фиксации , являются просто переформатированными версиями результатов двух git diff --name-status -ов.

Эти два относительно массивных git diff с может занять много времени, но это не так. Это по двум причинам:

  1. При --name-status сравнение двух коммитов или одного коммита и индекса может go очень быстро, потому что каждый файл в коммит сохраняется с помощью чего-то, что Git вызывает объект дерева , а индекс имеет форму, очень похожую на уплощенную серию объектов дерева. Все файлы в коммите и в индексе имеют предварительно вычисленные хэши. Операция разницы может просто сравнить хэши, чтобы выяснить, отличается ли файл. (Наличие или отсутствие файла определяет добавленные и удаленные статусы. Обнаружение переименования, если оно должно выполняться, может быть медленным.)

  2. С --name-status сравнение индекса и вашего рабочего дерева может go довольно быстро, потому что индекс кэширует информацию о вашем рабочем дереве. 2 Для каждого файла, для которого действительны данные кэша, Git не обязательно заглядывать внутрь файла рабочего дерева. Для файлов, в которых данные кэша недействительны, Git может иногда сразу узнать, что копия файла рабочего дерева не соответствует индексной копии. Это обычно оставляет лишь несколько сложных случаев, когда Git действительно нужно проверить, что копия рабочего дерева соответствует или не совпадает с индексной копией.


1 Технически, в индексе есть проверка непротиворечивости ha sh, и он действительно читает индекс, поэтому есть один га sh. Но это для index , который не является файлом, который вы можете зафиксировать.

2 Основным узким местом здесь является скорость, с которой ваша ОС может работать lstat system звонки. Или, по крайней мере, так и должно быть; некоторые версии Git случайно вводили поведение quadrati c в некоторых угловых случаях. Если lstat вызывает медленно , вы можете отключить их для указанных c файлов с помощью git update-index --assume-unchanged, хотя это означает, что Git просто предполагает, что файл не был изменен. Этот «пропустить медленный lstat» был его первоначальной целью. Git разрешено в любом случае разрешать статистику файла, поэтому --skip-worktree рекомендуется для скрытия изменений рабочего дерева.

...