Voici un autre moyen :
git ls-tree -r --name-only HEAD -z | TZ=UTC xargs -0n1 -I_ git --no-pager log -1 --date=iso-local --format="%ad _" -- _
Modifications des réponses données précédemment :
- Gère correctement les espaces dans les noms de fichiers.
- Utilisations
ls-tree
au lieu de ls-files
et en tant que tel, il peut être utilisé avec des dépôts nus.
- Imprime toutes les heures avec un décalage de zéro (UTC) dans le format ISO 8601. Cela permet un tri correct également pour les heures proches des changements d'heure d'été (ou commits de différents fuseaux horaires) en annexant
| sort
à la commande.
- Il n'est pas nécessaire d'utiliser des sous-shells, les performances devraient donc être aussi bonnes que possible.
Notez que cela ne gère pas correctement les noms de fichiers avec le caractère %
caractère. Voir ci-dessous pour une commande plus élaborée permettant de gérer correctement tous les caractères dans les noms de fichiers.
Notez que cette commande est toujours très lente car Git ne stocke pas vraiment les informations que nous recherchons. Techniquement, cela passe en revue tous les fichiers, filtre toutes les modifications apportées à un fichier donné à partir de l'ensemble de l'historique du projet, prend le dernier commit et imprime son timestamp d'auteur. En conséquence, les heures affichées correspondent au dernier commit qui a modifié chaque fichier. Si le fichier avait un horodatage différent sur le disque au moment où le commit original a été fait, il n'a jamais été stocké nulle part dans le dépôt Git et en tant que tel il ne peut jamais être restauré sans une source de données externe.
Si vous voulez définir les temps de modification du système de fichiers au dernier auteur commit temps de chaque fichier, vous pouvez faire quelque chose comme ceci pour traiter les caractères spéciaux dans les noms de fichiers (ajouter | bash
pour exécuter automatiquement toutes les commandes émises) :
git ls-tree -r --name-only HEAD -z | TZ=UTC xargs -0n1 git --no-pager log -1 --date=iso-local --name-only -z --format="format:%ad" | perl -npe "INIT {\$/ = \"\\0\"} s@^(.*? .*?) .*?\n(.*)\$@\$date=\$1; \$name=\$2; \$name =~ s/'/'\"'\"'/sg; \"TZ=UTC touch -m --date '\$date' '\$name';\n\"@se"
Même si cette commande est beaucoup plus complexe que la commande ci-dessus, les performances de cette commande devraient être à peu près égales à celles de la première, car les performances sont limitées par la recherche de la dernière heure de modification de chaque fichier au lieu de définir réellement l'heure de modification. Notez que cette commande convertit les heures en UTC, utilise des fichiers non séparés et réinitialise l'horodatage correct pour chaque fichier du système de fichiers en utilisant le fuseau horaire UTC tout en définissant l'heure.
Si l'ordre de sortie n'est pas strictement important, vous pouvez améliorer la performance de cette commande en ajoutant -P $(nproc)
a xargs
pour adapter Git à tous les processeurs, ce qui donne à la commande l'aspect suivant ...TZ=UTC xargs -0n1 -P $(nproc) git...
.
Si vous préférez l'heure du committer plutôt que la date de l'auteur, utilisez %cd
au lieu de %ad
dans la ligne de commande ci-dessus.