Ключ заключается в том, чтобы зафиксировать правильный контент, а именно:
- только какие были этапы (и добавлены в указатель)
- плюс некоторые модификации, представленные хуком предварительной фиксации
Первая точка достигается через git diff-index
Сравнивает содержимое и режим больших двоичных объектов, найденных с помощью объекта дерева, с содержимым текущего индекса и, при необходимости, игнорируя состояние статистики файла на диске.
exec git diff-index --check --cached $against --
с опцией --cached
:
вообще не учитывать файл на диске
Любое изменение затем учитывается как часть нового коммита.
Вы можете посмотреть источник commit.c :
static int prepare_to_commit(const char *index_file, const char *prefix,
struct wt_status *s)
{
...
if (!no_verify && run_hook(index_file, "pre-commit", NULL))
return 0;
...
/*
* Re-read the index as pre-commit hook could have updated it,
* and write it out as a tree. We must do this before we invoke
* the editor and after we invoke run_status above.
*/
discard_cache();
read_cache_from(index_file);