Еще в commit c64b9b8 (git 0.99, май 2005 г.) время всегда было упоминается как
<date>
Дата в секундах с эпохи'
фиксация 6eb8ae0 определяет дату как unsigned long
с апреля 2005 года.
TLDR;
дата до эпохи unix может быть сохранена, но не может быть уверена, что она будет правильно представлена.
Но это изменилось с 2014 года (см. в конце)
Попытка представить дату до предпринималась ранее: см. эта тема
Дата, которую я пытаюсь установить, — 4 октября 1958 года, то есть около метки времени -354808800.
Первый метод, используя флаги фиксации --date
с ISO 8601: он говорит «invalid date
».
Второй метод, описанный в архиве git ml, не с помощью фарфора:
git commit
git cat-file -p HEAD > tmp.txt
# at this point, edit the file to replace the timestamp
git hash-object -t commit -w tmp.txt
#=> 2ee8fcc02658e23219143f5bcfe6f9a4615745f9
git update-ref -m 'commit: foo' refs/heads/master \
2ee8fcc02658e23219143f5bcfe6f9a4615745f9
Дата фиксации эффективно обновляется, но git show
фиксирует дату до нуля (Jan 1 1970
). tig(1)
отображает 55 years ago
, поэтому фактическая дата фиксации сохраняется правильно.
Последняя проблема: при попытке отправить эту фиксацию в удаленный репозиторий:
#=> remote: error: object 2ee8fcc02658e23219143f5bcfe6f9a4615745f9:invalid
# author/committer line - bad date
#=> remote: fatal: Error in object
#=> error: unpack failed: index-pack abnormal exit
Наконец, при запуске test-date
из исходников git:
./test-date show -354808800
#=> -354808800 -> in the future
В обсуждении в то время упоминалось:
Я не уверен, что на самом низком уровне нет непереносимости.
Мы свободно переключаемся между time_t и unsigned long в низкоуровневом коде даты. Вероятно, это сработает, потому что переключение битов между подписанными и беззнаковыми типами обычно работает, если вы в конечном итоге получаете нужный тип.
Но это не обязательно переносимо, и могут быть тонкие ошибки. . См., например, мой недавний 9ba0f033.
Хорошая новость в том, что это чисто проблема с кодом. Формат данных в порядке. Просто кто-то просматривает код и переключает все «unsigned long
» на «long long
» (или time_t
, или даже «gittime_t
», если мы хотим абстрагироваться).
и исправление алгоритма парсера хотя бы в tm_to_time_t()
Это не просто "sed s/unsigned long/long long
", а проверка каждого изменения, чтобы убедиться, что вы не добавляете новых ошибок и что код правильно обрабатывает подписанные типы.
Вот почему никто этого не сделал. Это. ;)
Как я упоминал в 2017 году, в статье «Использовать будущую дату при совершении коммитов git" Git начал использовать другой и специализированный timestamp_t
тип.
Как показано в Legilibre/Archeo-Lex, выпуск 47:
Даты теперь используют тип timestamp_t
, определенный как typedef uintmax_t timestamp_t;
, вместо типа unsigned long
, чтобы исправить некоторые проблемы на 32-битных платформах... и 64-битных Windows ^^.
В проекте archeo-lex.fr (который зависит от более старых дат) используется git hash-object в сочетании с средство просмотра репозитория Git Legilibre/Archeo-Lex-web
.
Сейчас (февраль 2019 г.) это сделано , как прокомментировано пользователем Seb35
person
VonC
schedule
27.07.2014