web-dev-qa-db-fra.com

Comment récupérer la dernière date de modification de tous les fichiers dans un référentiel git

Je sais comment récupérer la dernière date de modification d'un seul fichier dans un référentiel git:

git log -1 --format="%ad" -- path/to/file

Existe-t-il un moyen simple et efficace de faire de même pour tous les fichiers actuellement présents dans le référentiel?

70
Eric Bréchemier

Une réponse simple serait de parcourir chaque fichier et d'afficher son heure de modification, à savoir:

git ls-tree -r --name-only HEAD | while read filename; do
  echo "$(git log -1 --format="%ad" -- $filename) $filename"
done

Cela produira une sortie comme ceci:

Fri Dec 23 19:01:01 2011 +0000 Config
Fri Dec 23 19:01:01 2011 +0000 Makefile

De toute évidence, vous pouvez contrôler cela car ce n'est qu'un script bash à ce stade - alors n'hésitez pas à personnaliser selon le contenu de votre cœur!

80
Andrew M.

Cette approche fonctionne également avec les noms de fichiers contenant des espaces:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {}

Exemple de sortie:

2015-11-03 10:51:16 -0500 .gitignore
2016-03-30 11:50:05 -0400 .htaccess
2015-02-18 12:20:26 -0500 .travis.yml
2016-04-29 09:19:24 +0800 2016-01-13-Atlanta.md
2016-04-29 09:29:10 +0800 2016-03-03-Elmherst.md
2016-04-29 09:41:20 +0800 2016-03-03-Milford.md
2016-04-29 08:15:19 +0800 2016-03-06-Clayton.md
2016-04-29 01:20:01 +0800 2016-03-14-Richmond.md
2016-04-29 09:49:06 +0800 3/8/2016-Clayton.md
2015-08-26 16:19:56 -0400 404.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-bradycardia-algorithm.htm
2015-12-23 17:03:51 -0500 _algorithms/acls-pulseless-arrest-algorithm-asystole.htm
2016-04-11 15:00:42 -0400 _algorithms/acls-pulseless-arrest-algorithm-pea.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-secondary-survey.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-suspected-stroke-algorithm.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-tachycardia-algorithm-stable.htm
...

La sortie peut être triée par horodatage de modification en ajoutant | sort jusqu'à la fin:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {} | sort
24

Ceci est un petit ajustement de la réponse d'Andrew M. (Je n'ai pas pu commenter sa réponse.)

Mettez le premier $ filename entre guillemets, afin de prendre en charge les noms de fichiers avec des espaces intégrés.

git ls-tree -r --name-only HEAD | while read filename; do
    echo "$(git log -1 --format="%ad" -- "$filename") $filename"
done

Exemple de sortie:

Tue Jun 21 11:38:43 2016 -0600 subdir/this is a filename with spaces.txt

J'apprécie que la solution d'Andrew (basée sur ls-tree) fonctionne avec des référentiels nus! (Ce n'est pas le cas des solutions utilisant des fichiers ls.)

6
Kevin G.

Pour ceux d'entre nous qui utilisent Windows et PowerShell, la réponse d'Andrew M, avec le Tweak lisible par ordinateur:

git ls-tree -r --name-only HEAD | ForEach-Object { "$(git log -1 --format="%ai" -- "$_")`t$_" }

Exemple de sortie:

2019-05-07 12:00:37 -0500   .editorconfig
2016-07-13 14:03:49 -0500   .gitattributes
2019-05-07 12:00:37 -0500   .gitignore
2018-02-03 22:01:17 -0600   .mailmap
1
James Skemp

Voici la version Shell de poisson de la réponse d'Andrew M, pour ceux qui utilisent du poisson.

git ls-tree -r --name-only HEAD | while read -l filename
    printf '%s %s\n' (git log -1 --format="%ai" -- $filename) $filename
end

Je stocke cela comme une fonction poisson pour un accès facile.

1
Kevin Cherepski