Як отримати останню дату зміни всіх файлів у сховищі git


64

Я знаю, як отримати останню дату модифікації одного файлу у сховищі git:

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

Чи є простий та ефективний спосіб зробити те ж саме для всіх файлів, які зараз перебувають у сховищі?

Відповіді:


74

Проста відповідь - це повторити кожен файл і відобразити його час модифікації, тобто:

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

Це дасть вихід таким чином:

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

Очевидно, ви можете керувати цим, оскільки в цьому моменті це просто баш сценарій - тому сміливо налаштовуйте під вміст свого серця!


2
Я сподівався, що є можливість отримати комбінований вихід за один цикл журналу git, але ваша відповідь краща за ту, яку я мав на увазі, використовуючи find. Я не знав git-ls-tree, яке має перевагу в тому, щоб перелічити лише файли, що зберігаються у сховищі, пропустивши папку .git та проігнорувавши файли. Дякую.
Ерік Бреч'єр

Без проблем, Еріку; ви слідуєте тим самим маршрутом, що і я - тобто робите пошук і ігноруєте каталог .git! :) Можливо, є кілька варіантів використання команд git сантехніка, але, чесно кажучи, це працює досить добре. Якщо ви могли знайти якийсь спосіб одержати інформацію одразу за кожним файлом відразу, це було б найкраще - але пам’ятайте, git працює на стані комітетів, а не на стані окремих файлів.
Ендрю М.

11
Я рекомендую використовувати --format = "% ai", якщо ви хочете відсортувати часові позначки замість читаних людьми дат.
ThorSummoner

2
Оскільки "HEAD" - це лише посилання, ви можете використовувати будь-яку потрібну вам посилання, будь то тег, гілка, введіть хеш тощо.
Ендрю М.

1
як сказав @ThorSummoner, використовуйте формат% ai для дати, а потім просто перейдіть для сортування результатів:git ls-tree -r --name-only HEAD | while read filename; do echo "$(git log -1 --format="%ai" -- $filename) $filename"; done | sort
Джон Хант

21

Цей підхід також працює з назви файлів, які містять пробіли:

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

Приклад виводу:

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

Вихід може бути відсортований за часовою міткою модифікації, додавши | sortдо кінця:

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

Будь-який спосіб отримати це сортування за часовою міткою модифікації?
Амеліо Васкес-Рейна

1
@ AmelioVazquez-Reina: Просто додайте `| sort` до кінця команди.
dotancohen

2
Це працює, але займає довгий час ...
Гільошон

5

Це невеликий твіст відповіді Андрія М. (Я не зміг прокоментувати його відповідь.)

Оберніть перше ім’я $ $ у подвійні лапки , щоб підтримувати назви файлів із вбудованими пробілами.

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

Вибірка зразка:

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

Я ціную, що рішення Ендрю (засноване на ls-tree ) працює з голими сховищами! (Це не стосується рішень, що використовують ls-файли.)


Ви також можете пропустити ехо: git log -1 --format = "% ad $ filename"
Кевін Ліда

0

Ось версія рибної шкаралупи відповіді Ендрю М для тих, хто вживає рибу.

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

Я зберігаю це як функцію риби для легкого доступу.


0

Для тих із нас, хто використовує Windows та PowerShell, відповідь Ендрю М із зручним для читання комп'ютером:

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

Приклад виводу:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.