Как git так быстро обнаруживает модификацию файла?
Имеет ли хэш каждый файл в репо и сравнивает SHA1? Это займет много времени, не так ли?
Или он сравнивает atime
, ctime
или mtime
?
Как git так быстро обнаруживает модификацию файла?
Имеет ли хэш каждый файл в репо и сравнивает SHA1? Это займет много времени, не так ли?
Или он сравнивает atime
, ctime
или mtime
?
Git пытается убедить себя в том, что только одно значение lstat() указывает, что рабочая строка соответствует индексу, потому что падение содержимого файла очень дорого.
Документация/технический/racy- git.txt описывает, какие поля статистики используются, и как некоторые условия гонки из-за низкой гранулярности времени избегают. В этой статье содержится более подробная информация.
значения статистики не являются защищенными от несанкционированного доступа, см. futimens (3). Git может быть обмануто отсутствием изменения файла; что не нарушает целостность хэширования содержимого.
Там начальная проверка времени для отчетов, таких как "git status", но когда вычисляется окончательный коммит, mtimes не имеет значения... это имеет значение SHA1.
Хорошо, мне было бы опасно предположить, что он использует комбинацию вызовов stat()
для разработки того, что похоже, возможно, изменилось, а затем, в свою очередь, действительно привязано к тому, чтобы установить с помощью этого diff'ing движок, что это так.
Здесь вы можете увидеть код для механизма diff здесь. Я проследил через кодовую базу, чтобы убедиться, что команда статуса действительно вызывается в этот код (это похоже на то, что много чего делает!), И на самом деле все это имеет большой смысл, когда вы знаете, что Git работает довольно плохо Windows, где он использует слой эмуляции для выполнения этих вызовов типа POSIX: он на порядок медленнее выполняет git status
на этой платформе.
Во всяком случае, не прочитав весь код сверху донизу (который я могу позже, если у меня есть время!), насколько я могу взять вас на данный момент... может быть, кто-то может быть более окончательным, если бы они работали с кодовая база.
Примечание. Еще одно возможное ускорение исходит из разумного использования функций inline
, где это явно имеет смысл, вы можете ясно видеть это в заголовках.
[edit: см. здесь для объяснения stat()
]
В зависимости от платформы вы сможете узнать, какие системные вызовы Git использует для определения своего статуса. Попробуйте strace git status
в Linux, truss git status
на SunOS или, похоже, DTrace-инструмент, который Apple поставляется с инструментами разработчика на Mac OS X.