Как получить дату последнего изменения всех файлов в репозитории мерзавца

Ваш NAT мешает. А именно, возвращаемые пакеты имеют адрес первоисточника, поскольку dest и как таковой не проходят через устройство NAT, чтобы быть de-NATted.

65
задан 22 June 2012 в 22:41
7 ответов

Простым ответом было бы перебрать каждый файл и отобразить время его модификации, то есть:

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

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

75
ответ дан 28 November 2019 в 19:31

Для тех из нас использующий Windows и PowerShell, ответ M Andrew, с компьютером читаемая тонкая настройка:

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

Для тех из нас использующий Windows и PowerShell, ответ M Andrew, с компьютером читаемая тонкая настройка:

[110]

Пример произвел:

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
")`t

Для тех из нас использующий Windows и PowerShell, ответ M Andrew, с компьютером читаемая тонкая настройка:

[110]

Пример произвел:

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
" }

Пример произвел:

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
0
ответ дан 28 November 2019 в 19:31

Этот подход также работает с имена файлов, содержащие пробелы:

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

Вывод можно отсортировать по метке времени изменения, добавив | отсортируйте до конца:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {} | sort
21
ответ дан 28 November 2019 в 19:31

Это небольшая поправка к ответу Эндрю М.. (Я не смог прокомментировать его ответ.)

Заключите первое имя $ filename в двойные кавычки , чтобы поддерживать имена файлов со встроенными пробелами.

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-файлы.)

5
ответ дан 28 November 2019 в 19:31

যারা মাছ ব্যবহার করেন তাদের জন্য এখানে অ্যান্ড্রু এম এর উত্তরের ফিশ শেল সংস্করণ।

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

আমি সহজেই অ্যাক্সেসের জন্য এটি ফিশ ফাংশন হিসাবে সঞ্চয় করি [

0
ответ дан 28 November 2019 в 19:31

Вот еще один ответ:

git ls-tree -r --name-only HEAD -z | TZ=UTC xargs -0n1 -I_ git --no-pager log -1 --date=iso-local --format="%ad _" -- _

Изменения в ранее данных ответах:

  • Правильно обрабатывает пробелы в именах файлов.
  • Использует ls-tree вместо ls-files и поэтому может использоваться с голыми репозиториями.
  • Печатает все время с нулевым смещением (UTC) в формате, подобном ISO 8601. Это позволяет правильно сортировать также время, близкое к переходу на летнее время (или фиксации из разных часовых поясов), добавляя | sort в команду.
  • Не требует использования подоболочек, поэтому производительность должна быть максимально возможной.

Обратите внимание, что это неправильно обрабатывает имена файлов с символом %. См. ниже более сложную команду для правильной обработки всех символов в именах файлов.

Обратите внимание, что эта команда все еще очень медленная, потому что Git на самом деле не хранит информацию, которую мы ищем. Технически это просматривает все файлы, фильтрует все изменения в любом данном файле из всей истории проекта, берет последний коммит и печатает временную метку его автора. В результате отображаемое время соответствует времени последней фиксации, которая изменила каждый файл. Если файл имел другую метку времени на диске во время исходной фиксации, он никогда не сохранялся нигде в репозитории git, и поэтому его невозможно восстановить без внешнего источника данных.

Если вы хотите установить время модификации файловой системы в соответствии с последним временем фиксации автором каждого файла, вы можете сделать что-то подобное для обработки специальных символов в именах файлов (добавьте | bash для автоматического выполнения всех испускаемых команд) :

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"

Несмотря на то, что это намного сложнее, чем приведенная выше команда, производительность этой команды должна быть примерно равна первой, потому что производительность ограничена поиском времени последней модификации каждого файла вместо фактической установки времени модификации. . Обратите внимание, что это преобразует время в UTC, использует файлы с нулевым разделителем и сбрасывает правильную отметку времени для каждого файла в файловой системе с использованием часового пояса UTC при установке времени.

Если порядок вывода не очень важен, вы можете повысить производительность этой команды, добавив флаги -P $(nproc) в xargs для масштабирования Git на все процессоры, делающие команда выглядит как ...TZ=UTC xargs -0n1 -P $(nproc) git... .

Если вы предпочитаете время фиксации вместо даты автора, используйте %cd вместо %ad в приведенной выше командной строке.

7
ответ дан 29 August 2020 в 10:52

Если вы пытаетесь установить время модификации файла в большом репозитории, посмотрите https://github.com/MestreLion/git-tools. Это уже упаковка.

sudo apt install git-restore-mtime
cd repo
git restore-mtime

он использует git whatschanged, а не git log, который намного быстрее на больших репо

4
ответ дан 30 September 2020 в 18:22

Теги

Похожие вопросы