Existe-t-il un moyen d’obtenir une date de diffusion pour un engagement donné?

Je me demande s’il existe un moyen de visualiser une date de diffusion associée à chaque validation dans le journal git. Si ce n’est pas possible, existe-t-il un moyen de voir tous les commits sous un certain coup de pouce.

J’écris un programme qui doit garder une trace des commits à mesure qu’ils sont poussés. Étant donné que le journal git est ordonné par la date de validation, et non par la date de diffusion, je ne suis pas en mesure de voir les derniers commits qui ont été poussés. Par exemple, si un utilisateur se connecte à son référentiel local 2 jours avant de transmettre au maître, cette validation sera placée 2 jours plus tard dans le journal du référentiel maître.

Il m’a fallu beaucoup de temps pour rassembler des informations dispersées et finalement trouver la meilleure réponse à cette question, mais maintenant je sais que je l’ai. En deux lignes seulement, pas de code ni de hook:

# required for a bare repo git config core.logAllRefUpdates true git reflog --date=local master 

Simple enfin.

Attention: vous voulez probablement remplacer les valeurs par défaut de gc.reflogExpire et gc.reflogExpireUnreachable . Vérifiez git help reflog pour plus de détails et pour comprendre comment et pourquoi cela fonctionne.

Les deux commandes ci-dessus doivent être exécutées dans le clone vers lequel vous poussez . Si ce n’est pas possible, une approximation doit être exécutée dans un autre clone permanent :

 git fetch origin # often and *regularly* git reflog --date=local origin/master 

Ne supprimez jamais ce clone permanent ou vous perdrez les dates.

Git est un système de contrôle de version dissortingbué, vous devez donc définir soigneusement ce que vous entendez par “date de diffusion”. Par exemple, supposons que l’utilisateur A envoie des validations au référentiel de l’utilisateur B. Quelque temps plus tard, l’utilisateur B envoie ces mêmes commits dans un troisième référentiel. À quelle date êtes-vous intéressé?

Je suppose que vous avez un référentiel partagé et que vous voulez que les utilisateurs de ce référentiel partagé puissent déterminer quand quelque chose a été publié dans le référentiel. Si c’est vrai, vous devrez collecter ces informations dans le référentiel partagé.

Les mauvaises nouvelles

Malheureusement, il n’y a aucun moyen d’append la date aux messages de validation. Cela changerait l’ID de validation (qui est un hachage SHA1 du contenu), causant toutes sortes de problèmes.

La bonne nouvelle

Heureusement, Git a une fonctionnalité (relativement nouvelle) appelée notes . Cette fonctionnalité vous permet de joindre du texte arbitraire à des validations, que git log peut afficher. Les notes peuvent être éditées et partagées avec d’autres.

Vous pouvez utiliser la fonctionnalité de notes pour attacher un message “cette validation a été reçue le [date]” à chaque validation telle qu’elle est reçue par le référentiel partagé.

Voir git help notes pour plus de détails.

Comment enregistrer la date

Voici l’approche que je recommande:

  1. Modifiez le hook post-receive de votre référentiel partagé pour parcourir chaque commit nouvellement accessible pour chaque référence mise à jour.
  2. Pour chaque commit, ajoutez quelque chose comme “[user] of [repository_url] a ajouté ce commit à [ref] le [date]” à la note du commit.

    Vous voudrez peut-être utiliser une note de référence dédiée à cet effet (comme refs/notes/received-on ) au lieu des refs/notes/commits par défaut. Cela évitera les conflits avec les notes créées à d’autres fins.

  3. Modifiez votre hook de receive pour refuser les mises à jour de votre référence de notes (pour empêcher les utilisateurs de jouer accidentellement ou intentionnellement avec les notes).
  4. Dites à tous les utilisateurs d’exécuter les commandes suivantes depuis leur arbre de travail:

     # Fetch all notes from the shared repository. # Assumes the shared repository remote is named 'origin'. git config --add remote.origin.fetch '+refs/notes/*:refs/remote-notes/origin/*' # Show all notes from the shared repository when running 'git log' git config --add notes.displayRef 'refs/remote-notes/origin/*' 

    Cette étape est nécessaire car Git ignore les références non-twigs, non-tag dans les référentiels en amont par défaut.

Ce qui précède suppose que les références sont uniquement avancées, jamais supprimées ou forcées. Vous voudrez probablement que le hook post-receive ajoute également les notes “Supprimé le [date]” pour gérer ces cas.

Jetez un coup d’œil au git reflog show master . Probablement pas le format exact que vous voulez, mais devrait vous orienter dans la bonne direction.

Une autre idée consiste à exécuter un script dans un hook push.

Cette réponse concernant l’inspection du refog sur la télécommande pourrait vous aider ( https://stackoverflow.com/a/8791295/336905 ) en vous donnant des informations sur la twig sur laquelle vous avez été poussé même si elle ne montre pas les commits qui ont été poussés, mais vous pourrait se corréler en trouvant la prochaine poussée après la date de validation locale. Pas infaillible, mais pratique si vous n’avez pas encore implémenté l’excellente suggestion de notes de @RichardHansen publiée plus tôt

Vous pouvez également consulter l’heure de modification du fichier de l’object de validation dans le répertoire “objects” du référentiel git sur le serveur lui-même.

Pourquoi git AuthorDate est différent de CommitDate?

  • AuthorDate est le moment où la validation a été créée pour la première fois.
  • CommitDate correspond à la dernière modification de la validation (par exemple, rebase).

Vous pouvez obtenir ceux avec les options de mise en forme --pretty :

  o %cd: committer date o %cD: committer date, RFC2822 style o %cr: committer date, relative o %ct: committer date, UNIX timestamp o %ci: committer date, ISO 8601 format 

Ainsi, si vous et d’autres développeurs git rebase avant de git rebase git push , vous obtiendrez une date de validation qui sera postérieure à la date de l’ auteur .

Cette commande affiche la date de validation: git log --pretty=fuller

 git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso 

Cela semble fonctionner plutôt bien pour moi. La date de repository (% cd) est trompeuse car elle n’est pas nécessairement identique à la date de diffusion. L’option –date = iso affichera cependant la date de push / fetch .

Notez que si vous avez récupéré l’origine / maître, la date à laquelle vous l’avez récupéré est imprimée. PAS la date à laquelle quelqu’un d’autre a poussé le commit.

  - %h: abrev. hash - %gd: human readable reflog selector - %gs: reflog subject - %s: subject/commit message 

Bonus: Vous pouvez bien sûr faire plus de mise en forme. Jusqu’à présent, j’aime ce code couleur. C’est un peu difficile à taper. Cela produira le SHA en rouge, le sélecteur de reflogging en cyan et le reflog en fonction du vert.

 git reflog show origin/master --pretty='format:%C(red)%h%Creset %C(cyan)%gd%Creset %C(green)%gs%Creset: %s' --date=iso 

Je suppose que vous pouvez utiliser la notation suivante pour obtenir la date de diffusion: git log -g –date = local