tipos tener tag remove qué proyecto practices podemos para nuestros mayor herramienta hacer existen etiquetas crear control best git timestamp epoch git-commit

tener - tipos de etiquetas en git



¿Es posible establecer un compromiso de git para tener una marca de tiempo antes de 1970? (4)

Acabo de girar con git hash-object y creé el siguiente objeto de confirmación:

tree 5efb9bc29c482e023e40e0a2b3b7e49cec842034 author x <[email protected]> -134607600 -0500 committer z <[email protected]> 1402404632 -0600 blah blah

Notarás que la fecha del autor se establece en un número negativo. Luego utilicé git update-ref para intentar vincular el objeto de confirmación ... sin suerte, obtengo el siguiente resultado cuando hago un registro de git:

$ git log commit 2303e7012001a3cc1c3dec806d0902008e1257a8 Author: x <[email protected]> Date: (null) blah blah

Sourcetree está igualmente confundido:

Parents: Author: x <[email protected]> Date: Monday, January 01, 0001 12:00:00 AM Committer: z <[email protected]> Commit Date: Tuesday, June 10, 2014 7:50:32 AM

(Creo que olvidé incluir el objeto de confirmación principal ...)

Del mismo modo, las fechas en el futuro lejano tampoco funcionan (lo que indica que probablemente no está tratando esto como un valor de 64 bits, incluso si es uno).

No estoy seguro de si esta respuesta califica como "no, no puedes hacer esto" o "sí puedes, pero no funciona bien". Uno necesitaría un cliente modificado para poder ver los registros de git con fechas correctas, eliminando cualquier posible beneficio para esto. Si alguien conoce un ingenioso comando git log que analice esas marcas de tiempo correctamente (¿se han ido a ese punto?!?!), Corríjame.

Las marcas de tiempo de Unix tienen enteros de 32 bits (64 bits en algunos sistemas hoy en día, o al menos eso entiendo). En algunos productos de software, esto le permite usar fechas que datan de 1903 más o menos.

Sin embargo, cuando intento lo siguiente:

git commit -m "this is a test commit" --date="1960-04-07 18:00:00"

Recibo un error "fatal: formato de fecha inválido".

Esto no es muy práctico (no soy un viajero del tiempo), pero me he estado preguntando sobre el uso de git con fines históricos. ¿Se puede forzar esto con un comando de plomería git? En una nota relacionada: ¿Git siempre usa una marca de tiempo de 32 bits, o esto depende del entorno en el que está basado?


Desde c64b9b8 (git 0.99, mayo de 2005), el tiempo siempre se ha referido como

<date>

Fecha en ''segundos desde la epoch ''

commit 6eb8ae0 define la fecha como unsigned long desde abril de 2005.

TLDR;

La fecha anterior a la época de Unix puede almacenarse, pero no puede asegurarse de estar representada correctamente.

Intentar representar una fecha antes se ha intentado antes: ver este hilo

La fecha que estoy tratando de establecer es el 4 de octubre de 1958, es decir, alrededor de la marca de tiempo -354808800.

Primera técnica, utilizando las --date commit --date con ISO 8601: dice " invalid date ".

Segunda técnica, descrita en el archivo git ml , sin usar la porcelana:

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

La fecha de compromiso se actualiza efectivamente, pero git show fija la fecha a cero ( Jan 1 1970 ). tig(1) muestra hace 55 years ago por lo que la fecha de compromiso real se almacena correctamente.

Último problema: cuando se intenta enviar este compromiso a un repositorio remoto:

#=> remote: error: object 2ee8fcc02658e23219143f5bcfe6f9a4615745f9:invalid # author/committer line - bad date #=> remote: fatal: Error in object #=> error: unpack failed: index-pack abnormal exit

Finalmente, cuando se ejecuta test-date de test-date de las fuentes de git:

./test-date show -354808800 #=> -354808800 -> in the future

La discusión en el momento mencionado:

No estoy seguro de que no haya alguna impureza en el nivel más bajo.
Intercambiamos libremente entre time_t y unsigned long en el código de fecha de bajo nivel. Probablemente funcione porque la conversión de bits entre los tipos firmados y no firmados generalmente funciona, siempre y cuando termine con el tipo que desea.
Pero no es necesariamente portátil, y puede haber errores sutiles. Ver, por ejemplo, mi reciente 9ba0f033 .

La buena noticia es que esto es puramente un problema de código. El formato de datos está bien. Solo tomaría a alguien pasar por el código y cambiar todo " unsigned long " a " long long " (o time_t , o incluso " gittime_t " si queremos abstraerlo).

y arreglando el algoritmo del analizador al menos en tm_to_time_t()

No es solo " sed s/unsigned long/long long ", sino que comprueba cada cambio para asegurarse de que no está introduciendo nuevos errores y que el código maneja correctamente los tipos firmados.
Por eso nadie lo ha hecho. ;)


Git mantiene las fechas internamente como una marca de tiempo de Unix y un desplazamiento de UTC, por lo que no es posible establecer una fecha de confirmación antes de la época de tiempo de Unix.

Debes estar ejecutando una versión de Git diferente a la que tengo en mi sistema CentOS 6.5 (que proporciona Git 1.7.1), al menos el tuyo te da un mensaje de error ... Si intento establecer una fecha de compromiso imposible utilizando Git 1.7. 1, la confirmación se realiza correctamente y utiliza silenciosamente la hora actual para la fecha de confirmación; Si intento la misma operación utilizando una fecha de confirmación "posible", tiene éxito y registra la fecha de confirmación prevista.


Puede guardarlos, pero nada los mostraría como esperaba (todavía).

El formato interno de Git almacena los datos de confirmación como una cadena numérica. p.ej:

$ git cat-file -p aa2706463fdeb51d6f9d0e267113b251888cf7f5 ... author Junio C Hamano <[email protected]> 1383318892 -0700 committer Junio C Hamano <[email protected]> 1383318892 -0700

No creo que se requiera que este número sea positivo. Sin embargo, la mayoría de las implementaciones, incluido git , lo analizan como un número sin firmar y no mostrarán esas fechas correctamente. Por ejemplo, en builtin/blame.c :

*time = strtoul(ident.date_begin, NULL, 10);

Asi que; el uso de tiempos negativos no es algo que pueda hacer fácilmente con las herramientas actuales, o mostrar con las herramientas actuales, pero el modelo de Git significa que los compromisos que incluyan sobrevivirán sin cambios en un repositorio.