Мне нужно, чтобы метки времени файлов на моем локальном и на моем сервере синхронизировались. Это достигается с помощью Subversion путем установки use-commit-times = true в конфигурации, чтобы последнее изменение каждого файла происходило при его фиксации.
Каждый раз, когда я клонирую свой репозиторий, я хочу, чтобы временные метки файлов отражали, когда они в последний раз были изменены в удаленном репозитории, а не когда я клонировал репозиторий.
Есть ли способ сделать это с помощью git?
git annex
может быть полезно для отслеживания изображенийОтветы:
Я не уверен, что это подойдет для DVCS (как в «Распределенной» VCS).
Огромное обсуждение уже состоялось в 2007 году (см. Эту ветку)
И некоторым из ответов Линуса эта идея не понравилась. Вот один пример:
(Примечание: небольшое улучшение: после оформления заказа временные метки актуальных файлов больше не изменяются (Git 2.2.2+, январь 2015 г.): «git checkout - как я могу поддерживать временные метки при переключении ветвей?» .)
Длинный ответ был:
источник
git
- это DVCS для управления исходным кодом, который будет встроен в ваш конечный продукт. Если вам нужна система распространения, вы знаете, где ее найтиrsync
.Однако, если вы действительно хотите использовать время фиксации для отметок времени при проверке, попробуйте использовать этот сценарий и поместите его (как исполняемый файл) в файл $ GIT_DIR / .git / hooks / post-checkout:
Обратите внимание, однако, что этот сценарий вызовет довольно большую задержку при проверке больших репозиториев (где большой означает большое количество файлов, а не большие размеры файлов).
источник
| head -n 1
следует избегать , поскольку это порождает новый процесс,-n 1
дляgit rev-list
иgit log
может быть использован вместо.`...`
иfor
; см. Почему вы не читаете строки с "for" . Я бы пошел наgit ls-files -z
иwhile IFS= read -r -d ''
.git show --pretty=format:%ai --abbrev-commit "$(get_file_rev "$1")" | head -n 1
вы могли это сделатьgit show --pretty=format:%ai -s "$(get_file_rev "$1")"
, это приводит к тому, чтоshow
команда генерирует намного меньше данных и снижает накладные расходы.ОБНОВЛЕНИЕ : мое решение теперь упаковано в Debian / Ubuntu / Mint, Fedora, Gentoo и, возможно, в другие дистрибутивы:
https://github.com/MestreLion/git-tools#install
IMHO, отказ от хранения меток времени (и других метаданных, таких как разрешения и владение) является большим ограничением
git
.Обоснование Линуса того, что временные метки вредны только потому, что они "сбивают с толку
make
", неубедительно :make clean
достаточно, чтобы исправить любые проблемы.Применимо только к проектам, использующим
make
, в основном, C / C ++. Это совершенно не подходит для таких скриптов, как Python, Perl или документации в целом.Будет только вред, если вы примените временные метки. Хранить их в репо не повредит . Их применение может быть простым
--with-timestamps
вариантом дляgit checkout
друзей (clone
иpull
т. Д.) По усмотрению пользователя .И Bazaar, и Mercurial хранят метаданные. Пользователи могут применять их или нет при оформлении заказа. Но в git, поскольку исходные временные метки даже не доступны в репо, такой опции нет.
Итак, для очень небольшого выигрыша (без необходимости заново компилировать все), специфичного для подмножества проектов,
git
поскольку общая DVCS была повреждена , некоторая информация о файлах потеряна , и, как сказал Линус, НЕОБХОДИМО сделать это сейчас. Грустно .Тем не менее, могу ли я предложить 2 подхода?
1 - http://repo.or.cz/w/metastore.git , Дэвид Хердеман. Пытается сделать то, что
git
должно было быть сделано в первую очередь : сохраняет метаданные (не только временные метки) в репозитории при фиксации (с помощью хука предварительной фиксации) и повторно применяет их при извлечении (также с помощью хуков).2 - Моя скромная версия скрипта, который я использовал раньше для создания архивов релизов. Как уже упоминалось в других ответах, подход немного отличается : применять для каждого файла , временная метка из самой последней фиксации , где был изменен файл.
Ниже приведена действительно простая версия скрипта в качестве доказательства концепции на Python 2.7. Для фактического использования я настоятельно рекомендую полную версию, указанную выше:
Производительность очень впечатляет, даже для монстра проектов
wine
,git
или даже ядра Linux:источник
git
делает магазин временные метки и т.д. Это просто не устанавливает временные метки по умолчанию. Просто посмотрите на результатgit ls-files --debug
git ls-files
работает с рабочим каталогом и индексом, поэтому это не означает, что он фактически хранит эту информацию в репо. Если бы он сохранил, получение (и применение) mtime было бы тривиальным.Я взял ответ Гила и вместо того, чтобы использовать сценарий ловушки после фиксации, включил его в свой собственный сценарий развертывания.
Обновление : я также удалил одно
| head -n
следующее предложение @eregon и добавил поддержку файлов с пробелами в них:источник
--abbrev-commit
вgit show
команде излишне--pretty=format:%ai
(хеш фиксации не является частью вывода) и| head -n 1
может быть заменен-s
флагом using togit show
%ai
дата автора, формат, подобный ISO 8601 , для строгого использования iso8601%aI
: git-scm.com/docs/git-showмы были вынуждены изобрести еще одно решение, потому что нам требовалось определенное время модификации, а не время фиксации, и решение также должно было быть переносимым (т.е. заставить python работать в установках git Windows действительно непросто) и быстро. Это напоминает решение Дэвида Хардемана, которое я решил не использовать из-за отсутствия документации (из репозитория я не смог понять, что именно делает его код).
Это решение хранит mtimes в файле .mtimes в репозитории git, обновляет их соответствующим образом при коммитах (только выборочно mtimes поэтапных файлов) и применяет их при оформлении заказа. Он работает даже с версиями git cygwin / mingw (но вам может потребоваться скопировать некоторые файлы из стандартного cygwin в папку git)
Решение состоит из 3-х файлов:
предварительная фиксация:
пост-расчет
mtimestore - bash:
mtimestore - c ++
дополнительную информацию можно найти здесь https://github.com/kareltucek/git-mtime-extension, некоторая устаревшая информация находится на http://www.ktweb.cz/blog/index.php?page=page&id=116
// редактировать - обновлена версия c ++:
// редактируем актуальную версию см. на github
источник
Следующий сценарий вобрал в
-n 1
иHEAD
предложения, работы в большинстве сред , отличных от Linux (как Cygwin), и может работать на кассе после факта:Предполагая, что вы назвали приведенный выше сценарий
/path/to/templates/hooks/post-checkout
и / или/path/to/templates/hooks/post-update
вы можете запустить его в существующем репозитории с помощью:источник
Это решение должно работать довольно быстро. Он устанавливает atimes на время коммиттера и mtimes на время автора. Он не использует никаких модулей, поэтому должен быть достаточно портативным.
источник
Вот оптимизированная версия вышеупомянутых решений оболочки с небольшими исправлениями:
источник
Вот метод с PHP:
Это похоже на ответ здесь:
Что эквивалентно времени использования-фиксации для git?
он создает список файлов, подобный этому ответу, но он строится из
git ls-files
него, а не просто просматривает рабочий каталог. Это решает проблему исключения.git
, а также решает проблему неотслеживаемых файлов. Кроме того, этот ответ не выполняется, если последняя фиксация файла была фиксацией слияния, с которой я решилgit log -m
. Как и другой ответ, он остановится, как только будут найдены все файлы, поэтому ему не нужно читать все коммиты. Например с:https://github.com/git/git
на момент публикации было прочитано всего 292 коммита. Также он игнорирует старые файлы из истории по мере необходимости и не трогает файл, который уже был затронут. Наконец, кажется, что это немного быстрее, чем другое решение. Результаты с
git/git
репо:источник
Я видел несколько запросов на версию для Windows, так что вот она. Создайте следующие два файла:
C: \ Program Files \ Git \ mingw64 \ share \ git-core \ templates \ hooks \ post-checkout
C: \ Program Files \ Git \ mingw64 \ share \ git-core \ templates \ hooks \ post-checkout.ps1
При этом используется git whatchanged , поэтому он просматривает все файлы за один проход вместо вызова git для каждого файла.
источник