Cara mengambil tanggal modifikasi terakhir dari semua file di repositori git

64

Saya tahu cara mengambil tanggal modifikasi terakhir dari satu file di repositori git:

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

Apakah ada cara sederhana dan efisien untuk melakukan hal yang sama untuk semua file yang ada di repositori?

Eric Bréchemier
sumber

Jawaban:

74

Jawaban sederhana adalah untuk beralih melalui setiap file dan menampilkan waktu modifikasinya, yaitu:

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

Ini akan menghasilkan output seperti:

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

Tentunya, Anda dapat mengontrol ini karena ini hanya skrip bash pada titik ini - jadi silakan menyesuaikannya dengan isi hati Anda!

Andrew M.
sumber
2
Saya berharap ada opsi untuk mendapatkan output gabungan dalam sekali pakai git log, tetapi jawaban Anda lebih baik daripada yang ada dalam pikiran saya menggunakan find. Saya tidak tahu git-ls-tree, yang memiliki keuntungan hanya dengan mendaftarkan file yang disimpan dalam repositori, melewatkan folder .git dan mengabaikan file. Terima kasih.
Eric Bréchemier
Tidak masalah, Eric; Anda mengikuti rute yang sama dengan yang saya lakukan - yaitu, mencari dan mengabaikan direktori .git! :) Mungkin ada beberapa opsi menggunakan perintah plumbing git, tapi sejujurnya, ini bekerja dengan cukup baik. Jika Anda dapat menemukan beberapa cara untuk mendapatkan informasi berdasarkan per file sekaligus, itu akan bekerja paling baik - tetapi ingat, git beroperasi pada status commit, bukan pada kondisi file individual.
Andrew M.
11
Saya sarankan menggunakan --format = "% ai" jika Anda ingin perangko waktu yang dapat diurutkan daripada tanggal yang dapat dibaca manusia.
ThorSummoner
2
Karena "KEPALA" hanyalah referensi, Anda dapat menggunakan referensi apa pun yang Anda inginkan, baik itu tag, cabang, komit, dll.
Andrew M.
1
sebagai @ThorSummoner berkata, gunakan format% ai untuk tanggal, dan kemudian hanya pipa untuk mengurutkan untuk mengurutkan hasil:git ls-tree -r --name-only HEAD | while read filename; do echo "$(git log -1 --format="%ai" -- $filename) $filename"; done | sort
John Hunt
21

Pendekatan ini juga berfungsi dengan nama file yang mengandung spasi:

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

Contoh output:

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
...

Output dapat diurutkan berdasarkan cap waktu modifikasi dengan menambahkan | sortsampai akhir:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {} | sort
William Entriken
sumber
Adakah cara untuk mendapatkan ini diurutkan berdasarkan cap waktu modifikasi?
Amelio Vazquez-Reina
1
@ AmelioVazquez-Reina: Cukup tambahkan `| sort` ke akhir perintah.
dotancohen
2
Ini bekerja tetapi membutuhkan waktu yang lama ...
Guillochon
5

Ini adalah perubahan kecil dari jawaban Andrew M. (Saya tidak dapat mengomentari jawabannya.)

Bungkus $ nama file pertama dalam tanda kutip ganda , untuk mendukung nama file dengan ruang tertanam.

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

Output sampel:

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

Saya menghargai bahwa solusi Andrew (berdasarkan ls-tree ) bekerja dengan repositori kosong! (Ini tidak berlaku untuk solusi yang menggunakan file ls.)

Kevin G.
sumber
Anda juga dapat melewati echo: git log -1 --format = "% ad $ filename"
Kevin Lyda
0

Ini adalah versi kulit ikan dari jawaban Andrew M, bagi mereka yang menggunakan ikan.

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

Saya menyimpan ini sebagai fungsi ikan untuk akses mudah.

Kevin Cherepski
sumber
0

Bagi kita yang menggunakan Windows dan PowerShell, jawaban Andrew M, dengan tweak yang dapat dibaca komputer:

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

Contoh output:

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
James Skemp
sumber