Git checkout - как я могу сохранять отметки времени при переключении ветвей?

Я часто переключаюсь между ветвями. У меня есть script, который подталкивает содержимое проверки в "запущенную" среду, где я могу увидеть запуск кода и протестировать его (это веб-приложение). Этот push script использует rsync в своем сердце, и он использует временные метки для определения того, какие файлы действительно должны быть переданы. Поскольку git -checkout, по-видимому, устанавливает временные метки в файлах в текущее время, rsync сообщает, что все файлы подталкиваются вверх, только потому, что временные метки будут обновляться.

Как я могу git -checkout сохранять метки времени при переключении между ветвями, чтобы rsync сообщал только о изменениях контента?

Я не хочу использовать аргумент контрольной суммы rsync, поскольку он очень медленный.

Ответ 1

Причина, по которой git checkout обновляет временные метки, заключается в том, что почти все системы сборки исходного кода зависят от временных меток, чтобы определить, нужно ли перестраивать цели. Если git checkout не обновляло временные метки на файлах при их обновлении, эти системы сборки неправильно выполняли бы инкрементную сборку. Фактически, git checkout должен обновлять временные метки только для файлов, которые были изменены.

rsync должен быть эффективным при обновлении штампов времени и не передавать какие-либо данные, только если изменились только метаданные. Вы можете проверить это с помощью "ускорения". Вы также можете задать последние версии rsync для изменения изменений с помощью флага -i. Вы можете сказать rsync не использовать временные метки (и использовать только контрольные суммы), оставив -a или -t, но не рекомендованные man-страницей rsync(1).

Ответ 2

Ситуация (в отношении git checkout и timestamps) должна быть лучше с git 2.2.2+ (январь 2015 г.).

Временная метка больше не должна перемещаться для файлов, которые уже обновлены при выполнении git checkout.

Смотрите commit c5326bd Джефф Кинг (peff):

checkout $tree: не выбрасывайте неизменные записи индекса

Когда "git checkout $tree", мы:

  • вытащите пути из $tree в индекс, а затем
  • проверить полученные записи в рабочей группе.

Наш метод для первого шага довольно тяжелый; он захватывает всю существующую запись индекса, даже если контент одинаков.
Это означает, что мы теряем информацию о статах, переходя checkout_entry к более поздним перепишите весь файл с идентичным контентом.

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

  • Мы гарантируем, что файл, который не имеет изменений, не переписан.
  • Мы проверяем, что мы обновляем файл, который не изменяется в индексе (по сравнению с $tree), но имеет изменения рабочего дерева.
    Мы сохраняем старый индекс, и checkout_entry может понять, что наша информация о статах устарела.

Ответ 3

Похоже, единственная причина, по которой это делается, заключается в том, что в среде DVCS вы можете использовать старый файл timestamp для обновления нового файла временной метки и вызвать проблему с сборкой. Я не думаю, что это хорошо, потому что редко мы используем старый файл timestamp для обновления нового файла временной метки.

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

    file_timestamp = (метка времени (B) > временная метка (A))? метка времени (B): временная метка (ТЕКУЩЕЕ);

  • или, это может быть спроектировано как настраиваемый параметр.