Куда "git update-index --assume-неизмененный файл" фактически сохраняет эту информацию? - PullRequest
10 голосов
/ 19 августа 2011

Мне нравится изменять конфигурационные файлы напрямую (например, .gitignore и .git / config) вместо запоминания произвольных команд, но я не знаю, где Git хранит ссылки на файлы, которые передаются в "git update-index --assume файл ".

Если знаешь, пожалуйста, скажи!

Ответы [ 2 ]

4 голосов
/ 19 августа 2011

Здесь указано, где в команде - git update-index

То есть вы не можете редактировать индекс, поскольку он не является текстовым файлом.

Кроме того, чтобы подробнее узнать о том, что хранится с помощью команды git update-index --assume-unchanged, см. Раздел Using “assume unchanged” bit в руководстве

2 голосов

Как говорили другие, он хранится в индексе, который находится по адресу .git/index.

После некоторой детективной работы я обнаружил, что она находится в: допустим бит каждой записи индекса.

Поэтому, прежде чем понять, что следует, вы должны сначала понять глобальный формат индекса, как объяснено в моем другом ответе .

Далее я объясню, как я убедился, что бит «предположим, что действительный» является виновником:

  • эмпирически
  • прочитав источник

Эмпирические

Время до hd.

Установка:

git init
echo a > b
git add b

Тогда:

hd .git/index

Дает:

00000000  44 49 52 43 00 00 00 02  00 00 00 01 54 e9 b6 f3  |DIRC........T...|
00000010  2d 4f e1 2f 54 e9 b6 f3  2d 4f e1 2f 00 00 08 05  |-O./T...-O./....|
00000020  00 de 32 ff 00 00 81 a4  00 00 03 e8 00 00 03 e8  |..2.............|
00000030  00 00 00 00 e6 9d e2 9b  b2 d1 d6 43 4b 8b 29 ae  |...........CK.).|
00000040  77 5a d8 c2 e4 8c 53 91  00 01 62 00 c9 a2 4b c1  |wZ....S...b...K.|
00000050  23 00 1e 32 53 3c 51 5d  d5 cb 1a b4 43 18 ad 8c  |#..2S<Q]....C...|
00000060

Сейчас:

git update-index --assume-unchanged b
hd .git/index

Дает:

00000000  44 49 52 43 00 00 00 02  00 00 00 01 54 e9 b6 f3  |DIRC........T...|
00000010  2d 4f e1 2f 54 e9 b6 f3  2d 4f e1 2f 00 00 08 05  |-O./T...-O./....|
00000020  00 de 32 ff 00 00 81 a4  00 00 03 e8 00 00 03 e8  |..2.............|
00000030  00 00 00 00 e6 9d e2 9b  b2 d1 d6 43 4b 8b 29 ae  |...........CK.).|
00000040  77 5a d8 c2 e4 8c 53 91  80 01 62 00 17 08 a8 58  |wZ....S...b....X|
00000050  f7 c5 b3 e1 7d 47 ac a2  88 d9 66 c7 5c 2f 74 d7  |....}G....f.\/t.|
00000060

Сравнивая два индекса и глядя на глобальную структуру индекса , вы увидите, что единственные различия:

  • номер байта 0x48 (9-й в строке 40) изменен с 00 на 80. То, что - это наш флаг, первый бит флагов записи в кэш.
  • 20 байтов от 0x4C до 0x5F. Это ожидается, поскольку это SHA-1 по всему индексу.

Имеется также мнение, что SHA-1 записи индекса в байтах от 0x34 до 0x47 не учитывает флаги, поскольку он не изменился между обоими индексами. Вероятно, поэтому флаги размещаются после SHA, который учитывает только то, что предшествует ему.

Исходный код

Теперь посмотрим, согласуется ли это с исходным кодом Git 2.3.

Первый взгляд на источник update-index , grep assume-unchanged.

Это приводит к следующей строке :

{OPTION_SET_INT, 0, "assume-unchanged", &mark_valid_only, NULL,
  N_("mark files as \"not changing\""),
  PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, MARK_FLAG},
{OPTION_SET_INT, 0, "no-assume-unchanged", &mark_valid_only, NULL,
  N_("clear assumed-unchanged bit"),
  PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},

, поэтому значение сохраняется в mark_valid_only. Grep, и найти, что он используется только в одном месте :

if (mark_valid_only) {
  if (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG))
    die("Unable to mark file %s", path);
  return;
}

CE означает запись в кэш.

Быстрая проверка mark_ce_flags показывает, что:

if (mark)
  active_cache[pos]->ce_flags |= flag;
else
  active_cache[pos]->ce_flags &= ~flag;

Таким образом, функция в основном устанавливает или отменяет бит CE_VALID, в зависимости от mark_valid_only, который представляет собой три состояния:

  • оценка: --assume-unchanged
  • Снять отметку: --no-assume-unchanged
  • ничего не делать: значение по умолчанию 0 опции, установленной на {OPTION_SET_INT, 0

Далее, с помощью команды builtin/ мы видим, что никакое другое место не устанавливает значение CE_VALID, поэтому --assume-unchanged должна быть единственной командой, которая его устанавливает.

Флаг, однако, используется во многих местах исходного кода, что следует ожидать, поскольку он имеет много побочных эффектов, и он используется каждый раз, как:

ce->ce_flags & CE_VALID

, поэтому мы заключаем, что оно является частью поля ce_flags поля struct cache_entry.

Индекс указан в cache.h, потому что одной из его функций является кэш для быстрого создания коммитов.

Посмотрев на определение CE_VALID в cache.h и окружающих нас линиях, мы имеем:

#define CE_STAGEMASK (0x3000)
#define CE_EXTENDED (0x4000)
#define CE_VALID (0x8000)
#define CE_STAGESHIFT 12

Итак, мы заключаем, что это самый первый бит этого целого (0x8000), рядом с CE_EXTENDED, что соответствует моему более раннему эксперименту .

...