myList = [[1]*4] * 3
создает один объект списка [1,1,1,1]
в памяти и копирует его ссылку 3 раза. Это эквивалентно obj = [1,1,1,1]; myList = [obj]*3
. Любая модификация obj
будет отражена в трех местах, где obj
упоминается в списке. Правильным утверждением будет:
myList = [[1]*4 for _ in range(3)]
или
myList = [[1 for __ in range(4)] for _ in range(3)]
. Важно отметить, что *
оператор в основном используется для создания список литералов. Поскольку 1
является литералом, значит, obj =[1]*4
создаст [1,1,1,1]
, где каждый 1
будет атомарным, а не ссылкой 1
, повторяемым 4 раза. Это означает, что если мы obj[2]=42
, то obj
станет [1,1,42,1]
не [42,42,42,42]
, как могут предположить некоторые.
Еще совершает c64b9b8 (git 0.99, май 2005), время всегда упоминалось как
<date>
Дата в секундах с epoch '
commit 6eb8ae0 определяет дату как
unsigned long
с апреля 2005 года.TLDR;
]date до unix epoch может быть сохранен, но не может быть уверен, что он будет правильно представлен.
Попытка представить дату перед попыткой до: см. эта нить
Дата, которую я пытаюсь установить, - 4 октября 1958 года, которая находится вокруг timestamp -354808800.
Первая техника, используя флаги commit
--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
», а скорее проверка каждого изменения, чтобы убедиться, что вы не вводите новые ошибки, и что код правильно обрабатывает подписанные типы. Вот почему никто этого не сделал. ;)
Вы можете сохранить их, но ничто не покажет их, как вы ожидали (пока).
Внутренний формат Git сохраняет данные фиксации в виде числовой строки. например ::
$ git cat-file -p aa2706463fdeb51d6f9d0e267113b251888cf7f5
...
author Junio C Hamano <gitster@pobox.com> 1383318892 -0700
committer Junio C Hamano <gitster@pobox.com> 1383318892 -0700
Я не считаю, что требуется, чтобы это число было положительным. Однако большинство реализаций, включая git
, анализируют его как неподписанное число и не будут корректно отображать эти даты. Например, в builtin/blame.c
:
*time = strtoul(ident.date_begin, NULL, 10);
So; использование отрицательных времен - это не то, что вы можете легко сделать с текущими инструментами или отображать с помощью текущих инструментов, но модель Git означает, что коммиты, включая их, будут сохраняться без изменений в репозитории.
Я просто спрятался с git hash-object и создал следующий объект commit:
tree 5efb9bc29c482e023e40e0a2b3b7e49cec842034
author x <x@x.com> -134607600 -0500
committer z <z@z.com> 1402404632 -0600
blah blah
Вы заметите, что дата автора установлена на отрицательное число. Затем я использовал git update-ref, чтобы попытаться связать объект commit ... не повезло, я получаю следующий вывод, когда я делаю журнал git:
$ git log
commit 2303e7012001a3cc1c3dec806d0902008e1257a8
Author: x <x@x.com>
Date: (null)
blah blah
Sourcetree также смущен:
Parents:
Author: x <x@x.com>
Date: Monday, January 01, 0001 12:00:00 AM
Committer: z <z@z.com>
Commit Date: Tuesday, June 10, 2014 7:50:32 AM
(я думаю, что я забыл включить родительский объект фиксации ...)
Точно так же даты в далеком будущем тоже не работают (указывая, что он, вероятно, не обрабатывает это как 64-битное значение, даже если оно одно).
Я не уверен, что этот ответ квалифицируется как «нет, вы не можете этого сделать» или «вы можете, но он не работает» Что ж". Один из них нуждается в модифицированном клиенте, чтобы иметь возможность просматривать журналы git с правильными датами, удаляя все возможные выгоды для этого. Если кто-то знает отличную команду git log, которая будет правильно анализировать эти временные метки (они ушли в этот момент?!?!), Пожалуйста, исправьте меня.
Git внутренне поддерживает даты как временную метку Unix и смещение от UTC, поэтому невозможно установить дату фиксации до эпохи Unix.
Вы должны запускать другую версию Git, чем У меня на моей системе CentOS 6.5 (которая предоставляет Git 1.7.1), по крайней мере, у вас появляется сообщение об ошибке ... Если я попытаюсь установить невозможную дату фиксации с помощью Git 1.7.1, то коммит будет успешным и беззвучно будет использовать текущий время для даты фиксации; если я попытаюсь выполнить ту же операцию с использованием «возможной» даты фиксации, она будет успешной и запишет предполагаемую дату фиксации.