Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Affichage des dates inférieure à 1970 erroné #47

Closed
mdamien opened this issue Nov 20, 2017 · 20 comments
Closed

Affichage des dates inférieure à 1970 erroné #47

mdamien opened this issue Nov 20, 2017 · 20 comments

Comments

@mdamien
Copy link

mdamien commented Nov 20, 2017

Par exemple, sur cette page: https://archeo-lex.fr/codes/code-de-l%E2%80%99artisanat

image

Les commits eux aussi ont la mauvaise date:

commit 9d4ab729ba0f9346fb8f75155985f9530d568a2b
Author: Législateur <>
Date:   Tue Feb 6 00:00:00 2018 +0100

    Version consolidée au 18 juin 1954
    
    Versions :
    - base LEGI : 18 juillet 2014 11:30:10
    - programme Archéo Lex : 0.2.0-alpha

commit 605f346a69a5b2ee9f32979841a6964ceb9d2369
Author: Législateur <>
Date:   Fri Feb 7 00:00:00 2020 +0100

    Version consolidée au 20 juillet 1952
    
    Versions :
    - base LEGI : 18 juillet 2014 11:30:10
    - programme Archéo Lex : 0.2.0-alpha

La solution à l'air d'être d'utiliser un autre format que le timestamp pour spécifier la date: https://stackoverflow.com/questions/19742345/what-is-the-format-for-date-parameter-of-git-commit

Du coup, a cette ligne, en théorie il faudrait faire:

    ...ateur <>"', '--date=short:"' + debut..strftime("%Y-%m-%d") + '"', '-m', 'Version consolidée au...

Par contre, pas moyen de faire fonctionner cette solution. Du coup soit changer l'affichage des dates, soit regler les dates dans git.

@hashar
Copy link

hashar commented Nov 20, 2017

Voir le commentaire de @VonC sur https://stackoverflow.com/a/24977895 Il faut modifier le commit manuellement et la bonne date sera enregistrée dans le dépôt.

Toutefois git utilise généralement un format non signé unsigned long. Passer à un timestamp signé n'est pas forcément une modification triviale :D

@mdamien
Copy link
Author

mdamien commented Nov 20, 2017

ah oui, c'est pas du petit fix !

@fgallaire
Copy link
Member

@hashar un exemple de pourquoi #35 serait utile.

@JMLX42
Copy link
Member

JMLX42 commented Nov 21, 2017

@fgallaire c'est du au fonctionnement des timestamp. IMHO le problème sera le même quelque soit le VCS.

@fgallaire
Copy link
Member

@promethe42 j'ai beaucoup bossé sur ce problème, il y a trois limitations : une liée au type de donnée utilisé pour stocker la date (le unsigned long de Git), une autre liée à l'algo de calcul des dates qui fait des assomptions sur la date et la dernière sont les bugs de l'appel système gmtime() de Windows et des plateformes 32 bits.

J'ai étendu le support de mercurial du 1er janvier 1970 au 13 décembre 1901 :
https://www.mercurial-scm.org/repo/hg//rev/87c6ad2251d8
Et débuggé pour Windows et plateformes 32 bits celui de bazaar qui est le 1 janvier 1900 :
http://bazaar.launchpad.net/~bzr-pqm/bzr/bzr.dev/revision/6622

@JMLX42
Copy link
Member

JMLX42 commented Nov 23, 2017

@fgallaire merci pour l'info 👍

Cependant, j'ai du mal à imaginer que les corrections en questions ne trouvent pas preneur sur Git.
Il y'a une raison particulière pour laquelle tu n'as pas proposé de patch sur Git ?

@fgallaire
Copy link
Member

fgallaire commented Nov 24, 2017

@promethe42 Bah le problème c'est que c'est plus dur de contribuer à un logiciel utilisant des technos de merde...

Grâce à python et son typage dynamique, pour hg et bazaar il n'y avait en gros qu'à corriger les fonctions liées au timestamp dans un fichier ou deux.

Avec Git c'est une autre histoire, il faut modifier le unsigned long en long long dans tous les fichiers C et de header pour toutes les variables du genre t, time, timestamp, author_time, committer_time, date et autres, et modifier toutes les fonctions typées du genre strtoul en strtoll.

Donc déjà arriver à faire tout ça correctement sans rien oublier faut y aller. Une fois que c'est fait reste à réécrire complètement tous les algos du fichier date.c qui ne fonctionnent que pour des dates entre 1970 et 2099.

Une fois que c'est fait faut réussir à faire passer upstream un patch pareil en risquant de casser Git. Je soupçonne que ce patch ne se fera que le jour où Linus aura besoin d'une date antérieure à l'Epoch, et je ne suis pas sûr que cela arrive un jour.

@Seb35
Copy link
Member

Seb35 commented Dec 31, 2017

En plus des dates dans le passé, il y a la date 2222-02-22 qui est utilisée pour la valeur "date future indéterminée" qui n’est pas non plus bien enregistrée.
@fgallaire: merci pour tes patches sur hg et bazaar, ça donne un argument supplémentaire pour avoir d’autres moteurs de versionnement.
Pour Git, c’est effectivement assez compliqué, mais ça vaudrait le coup.

Pour Archéo Lex, dans l’immédiat, ça serait peut-être plus simple de contourner le problème au niveau de l’affichage (quitte à ce que ça soit faux dans le stockage Git), en utilisant le commentaire qui contient, lui, la bonne date.

@JMLX42
Copy link
Member

JMLX42 commented Jan 2, 2018

@fgallaire @Seb35 D'après ce qu'on m'a dit, Git n'a aucun problème avec le type de données pour stocker les dates. Mais ceux sont les clients - comme GitHub - qui interprètent mal les dates inférieures à 1/1/1970.

@Seb35
Copy link
Member

Seb35 commented Jan 2, 2018

J’ai testé le lien donné par @hashar (hello ! :), les commits avec un timestamp négatif ou supérieurs à l’année 2099 semblent bien enregistrés effectivement (avec ma version de git CLI 2.1.4), et l’affichage est correct pour les années > 2099 mais reste bloqué à 1970 pour les timestamps négatifs (et il semble que git CLI ne gère pas non plus le 1er janvier 1970 00:00:00 +01:00, probablement car le timestamp est négatif à -3600).

Données de test :

  • 2222-02-22 00:00:00 +01:00 = 7956831600 +0100
  • 1969-01-01 00:00:00 +01:00 = -31539600 +0100

Comme roadmap, je propose ;

  1. forcer l’enregistrement dans le stockage git des dates < 1970 et > 2099
  2. observer comme se comportent les principaux clients Git CLI et GitHub, voire Gitlab
  3. si concluant, en faire le format de stockage par défaut dans Archéo Lex
  4. si besoin, adapter l’interface web sur https://archeo-lex.fr (fork Gitlist)
  5. proposer un patch à Git CLI et en discuter sur la ml Git

@fgallaire
Copy link
Member

fgallaire commented Jan 2, 2018

D'après ce qu'on m'a dit, Git n'a aucun problème avec le type de données pour stocker les dates. Mais ceux sont les clients - comme GitHub - qui interprètent mal les dates inférieures à 1/1/1970.

@promethe42 La question venant de toi m'étonne, tu te bases sur des on-dit venant de on ne sait qui (ça ne devait pas être Linus...) alors que tu es un très bon développeur et que donc :

  • il te suffit de faire un commit avec l'option "--date" pour constater que ça ne marche pas
  • il te suffit de checkout le code source pour constater que le problème est bien dans git

Par ailleurs en jetant un nouveau coup d’œil, la situation a pas mal évolué (git/git@b15667b) depuis mes expérimentations sur git et ce que je vous ai raconté n'est plus totalement exact.

Les dates utilisent maintenant le type timestamp_t défini par typedef uintmax_t timestamp_t;en lieu et place du type unsigned long de manière à fixer certains problèmes en particulier sur plateformes 32 bits... et Windows 64 bits ^^. Cette réorganisation devrait permettre de fixer beaucoup plus facilement notre problème de date :

  • il suffit maintenant de fixer le type timestamp_t en un seul endroit.
  • le patch étant moins invasif/risqué il aura beaucoup plus de chance d'être accepté

@JMLX42
Copy link
Member

JMLX42 commented Jan 2, 2018

La question venant de toi m'étonne, tu te bases sur des on-dit venant de on ne sait qui (ça ne devait pas être Linus...) alors que tu es un très bon développeur et que donc :

Tu n'as pas fait preuve de beaucoup d'objectivité en disant que git était "un logiciel utilisant des technos de merde". La condescendance ne fera pas avancer le sujet.

il te suffit de faire un commit avec l'option "--date" pour constater que ça ne marche pas
il te suffit de checkout le code source pour constater que le problème est bien dans git

Avec quelle version de git ? quelle plateforme/archi ?
Il y'a une grande différence entre ce que git accepte en ligne de commande, ce que git stocke sur le disque et ce qu'il restitue dans l'affichage.
Donc ce test ne me paraît pas du tout pertinent.
Notamment puisqu'il s'agit ici de problèmes de représentation.

C'est beaucoup plus compliqué que ça, cf https://stackoverflow.com/a/24977895

(note que j'aurais pu écrire "il te suffit de faire une recherche Google ou dans la ML git")

Le "on dit" vient de Emmanuel Raviart avec qui on en a discuté, et qui a creusé le sujet lorsqu'il avait fait un programme pour générer directement des archives Git. En l'occurrence, il ne s'agit pas il me semble de changer le type utilisé pour stocker les dates, mais simplement d'utiliser des valeus négatives, qui sont correctement stockées dans Git (comme l'explique le post ci-dessus) et affichées correctement dans certains clients.

@fgallaire
Copy link
Member

fgallaire commented Jan 2, 2018

Avec quelle version de git ?

La dernière

quelle plateforme/archi ?

La tienne, Git est censé marcher partout non ? chez toi c'est un bon début

Il y'a une grande différence entre ce que git accepte en ligne de commande, ce que git stocke sur le disque et ce qu'il restitue dans l'affichage.

Si c'est la CLI de git qui doit être fixée, c'est bien que le problème ne vient pas de Github ou des autres clients.

Donc ce test ne me paraît pas du tout pertinent.
Notamment puisqu'il s'agit ici de problèmes de représentation.
En l'occurrence, il ne s'agit pas il me semble de changer le type utilisé pour stocker les dates,

Il me semble que mes posts sont assez argumentés mais bon :
gitster/git@a07fb05

Git's source code simply uses an incorrect data type for timestamps, is all.

Bon c'était pour expliquer pourquoi ça ne gérait pas les dates loin dans le futur. Mais ça s'applique encore pour les dates avant 1970.

mais simplement d'utiliser des valeus négatives, qui sont correctement stockées dans Git

Faux, le type utilisé est unsigned i.e. sans valeurs négatives, il suffit de lire le code source...

J'arrêterai sur ce sujet, ça à l'air de froisser les gens que Git ne fonctionne pas bien...

@JMLX42
Copy link
Member

JMLX42 commented Jan 2, 2018

chez toi c'est un bon début

Comme "tu es un bon développeur", je ne doute pas que tu aies lu mon post et les liens associés - ou même le lien que tu as toi même fourni - qui expliquent clairement que ces considérations dépendent de la plateforme et de la version de Git.

Donc comme "tu es un bon développeur", tu sais que tester avec mon git dans mon environnement n'aura pas plus de valeur que "on m'a dit".

Comme "tu es un bon développeur", tu sais aussi que pour avancer des affirmations aussi extraordinaires que "[le C] est une techno de merde", il faut des preuves en béton.
Et que par conséquent le minimum à faire et de produire un bout de code permettant de reproduire le problème.

Si c'est la CLI de git qui doit être fixée, c'est bien que le problème ne vient pas de Github ou des autres clients.

Justement. Non.
Comme expliqué dans mon post précédent :

Il y'a une grande différence entre ce que git accepte en ligne de commande, ce que git stocke sur le disque et ce qu'il restitue dans l'affichage.

Dans le post que je mentionne (https://stackoverflow.com/a/24977895) :

We freely interchange between time_t and unsigned long in the low-level date code. It probably happens to work because casting the bits back and forth between signed and unsigned types generally works, as long as you end up with the type that you want.
But it isn't necessarily portable

Donc contrairement à ce que tu prétends, la gestion des dates :

  • dépend de la plateforme (ironiquement, c'est même indiqué dans le commit que tu cites toi même...)
  • ne dépend pas simplement du type de donnée mais aussi de certains cast
  • il est à priori possible d'utiliser des valeurs négatives pour représenter les dates avant 1/1/1970 : elles sont bien stockées, et même si git-cli va les clamper à 1/1/1970, d'autres clients peuvent les afficher correctement.

Faux, le type utilisé est unsigned i.e. sans valeurs négatives, il suffit de lire le code source...

Tu ne sais manifestement pas ce qu'implique unsigned en C.
Ca n'est pas un problème en soit, mais c'est un peu dommage après avoir dit un truc du genre "[le C] est une techno de merde".

Les contenus que je mentionne explique très clairement pourquoi ton interprétation du problème n'est pas la bonne. Notamment la partie sur les casts.

J'arrêterai sur ce sujet, ça à l'air de froisser les gens que Git ne fonctionne pas bien...

Ca "froisse" surtout les gens que tu sois condescendant alors que tu ne lis manifestement pas les posts des autres.

Ca froisse aussi les gens quand tu les prends de haut en étant intransigeant sur un manque de rigueur dont tu fais toi cruellement défaut (cf "chez toi c'est un bon début").

Tout ce post n'ajoute aucune information au débat, mais tu me contraints à tout répéter par ce que mon post précédent n'a manifestement pas été lu. Voilà à quoi on en arrive...

@fgallaire
Copy link
Member

fgallaire commented Jan 2, 2018

Hum... je ne vais pas effectivement me répéter non plus, mes posts sont argumentés avec du code source, tout le monde peut constater que Git ne marche pas, que le code source ne gère pas les dates négatives, etc. Il me semble que donner des liens vers le code source fait montre d'une plus grande rigueur d'argumentation que toi qui argumentais avec des on-dit et des recherches sur Google. Tu craques complètement sur ce sujet j'arrête les frais.

@JMLX42
Copy link
Member

JMLX42 commented Jan 2, 2018

mes posts sont argumentés avec du code source

Tes posts montrent que ton interprétation est naïve au mieux, erronnée au pire.
Je cite (d'après tes propres liens) :

git/git@b15667b

Some platforms have ulong that is smaller than time_t

gitster/git@a07fb05

On 32-bit platforms, as well as on Windows, unsigned long is not large enough to
capture dates that are "absurdly far in the future".

Donc d'après tes propres références :

  • ça dépend bien de la plateforme ;
  • les modifications concernent les dates dans le futurs, pas nécessairement celles antérieures à 1/1/1970.
  • sur un linux 64bit les dates loin dans le futur devraient fonctionner.

As-tu un exemple qui prouve le contraire ?

que le code source ne gère pas les dates négatives

D'après ce post, tout le monde constate l'inverse, à savoir :

  • git gère - par effet des effets de bord liés à la gestion des cast signed/unsigned dans le standard C99 - les dates négatives et les inscrit comme telles sur le disque
  • git-cli les tronque au 1/1/1970, un autre client pourrait le faire différemment

As-tu un exemple qui prouve le contraire ?

@fgallaire
Copy link
Member

fgallaire commented Jan 3, 2018

Ce qui est drôle c'est que le "client" que tu appelles git-cli n'existe pas, il y a juste un dépôt qui s'appelle git, et tout le code dans ce dépôt est incapable de gérer les dates négatives... et on s'en rend compte en utilisant Git... Si il n'y a a aucun problème et que tout marche on pourrait juste arrêter d'en parler... Si j'ai le temps j'essayerai de fixer git qui marche déjà parfaitement...

Seb35 added a commit that referenced this issue Aug 17, 2018
Pour pallier à l’état de fait que les dates pré-1970 et post-2100 apparaissent
actuellement avec des dates "aléatoires", ces dates sont désormais détectées
et sont ramenées à des dates aux limites possibles.

Pour 1970, la première date acceptée est le 2 janvier 1970 (car le 1er janvier
1970 minuit CET n’est pas représentable, le binaire Git officiel inscrit
d’ailleurs l’entier signé (négatif) -3600 sur 64 bits (= 18446744073709548016
vu en entier signé sur 64 bits), ce qui fait buguer certaines interfaces comme
gitlist sur archeo-lex.fr). Les années avant 1970 étaient remplacées par des
dates plus ou moins aléatoires. Ces dates sont remplacées par le 1er janvier
1970 à 12:00:00 CET.

Pour 2100, la limite à 32 bits correspond à l’année 2105 et le binaire Git
interdit à partir de 2100. Il y a (sauf erreur dans la base LEGI) que la date
2222-02-22 qui est valide (date d’entrée en vigueur future non-déterminée).
Ces dates sont remplacées par le 1er janvier 2099 à 12:00:00 CET.

Noter que dans tous les cas la date réelle est inscrite dans le message de
commit en français. Ces limitations sont désormais détectées au cours de
l’exécution d’Archéo Lex et sont affichées lors de l’enregistrement de la
version ainsi qu’à la fin de l’exécution.

Une option pour forcer le stockage des dates réelles sera créée.

Issue: #47
@Seb35
Copy link
Member

Seb35 commented Aug 17, 2018

Du côté d’Archéo Lex, pour Git, c’est en passe d’être résolu avec une version dégradée mais compatible par défaut, celle que je viens de poucher, et des flags pour activer les dates pré-1970 et/ou post-2100, que je viens d’implémenter dans Archéo Lex – je nettoie le code et ça arrive.

Dans la version dégradée, les dates pré-2-janvier-1970 sont fixées au 1er janvier 1970 12:00:00 CET (pour éviter les dates "aléatoires" actuelles), et les dates post-2100 sont fixées au 1er janvier 2099 12:00:00 CET (normalement il n’y a que la date 2222-02-02). Bien sûr c’est pas extraordinaire pour les dates pré-1970 mais c’est un moindre mal.

Dans la version "vrais dates" à venir, j’ai donc utilisé git hash-object comme donné sur SO par @hashar. Tout est bien enregistré et peut être relu, au pire avec git log --pretty=raw. GitHub n’accepte pas les dates pré-1970 mais accepte les post-2100. Le binaire git officiel affiche les post-2100 mais pas les pré-1970. Les git push fonctionnent dans tous les cas pourvu qu’il n’y ait pas de hooks refusant ces dates.

Depuis hier, j’ai pas mal amélioré le site officiel archeo-lex.fr (basé le gitlist) – c’est dans le chemin /dev/, je ne le marque pas en lien pour éviter que ça soit crawlé – et modulo une petite adaptation de gitlist, qui utilise gitter qui utilise le binaire git, ça fonctionne avec les dates pré-1970 et bien sûr post-2100 (en modifiant l’appel avec un git log --pretty=raw lorsque nécessaire).

Merci à tous pour la recherche documentaire. Ça résoud pas les difficultés dans Git mais ça pourra donner des exemples pour tester le fonctionnement de tel ou tel client Git. En tous cas, avec un entier signé sur 64 bits, ça couvre ± 292x10^9 années, il faut juste pas qu’il y ait eu une loi le 30 février 1712.

@Seb35
Copy link
Member

Seb35 commented Aug 17, 2018

Un détail aussi, Git enregistre le fuseau horaire et Archéo Lex s’appuie sur pytz pour cela, avec le fuseau horaire de Paris (CET/CEST). Pour le code civil, créé en 1803, j’ai eu la surprise de voir que pytz inscrivait le fuseau horaire +0009 avant 1910, appelé LMT Local Mean Time, puisque les fuseaux horaires ont été déployés à la fin du XIXe siècle. Je laisse comme ça, j’imagine que ça a une signification de marquer +0009, mais si quelque veut chercher ou sait déjà on apprendra un truc (enfin, au moins moi).

Seb35 added a commit that referenced this issue Aug 19, 2018
Avant 1970 et après 2100, les dates sont forcées directement dans le
format de stockage Git en passant par `git hash-object`. Cela est
activé par deux flags. Ceux-ci peuvent rendre les dépôts créés
incompatibles avec certaines plateformes ou logiciels :
- le pré-1970 entraîne des timestamps négatifs,
- le post-2100 correspond à un entier de plus de 32 bits.

Issue: #47
@Seb35
Copy link
Member

Seb35 commented Feb 9, 2019

C’est implémenté et déployé en prod sur https://archeo-lex.fr depuis longtemps, c’est donc résolu côté Archéo Lex. Les dépôts créés sont refusés par GitHub et Gitlab, il n’est pas possible de les pousser (remote: error: object 0b8d258877dc76f794974fe10c8763e5662f769e: badDateOverflow: invalid author/committer line - date causes integer overflow).

Lors de la création des dépôts par AL, par défaut la version dégradée est créée (cf ci-dessus), et il faut explicitement indiquer les flags --dates-git-pre-1970 ou --dates-git-post-2100 ou --dates-git (ce dernier combine les deux). Ce dernier flag est utilisé sur https://archeo-lex.fr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants