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