やりたいこと
- ファイルの変更頻度を調べたい
- 追加したファイルや削除したファイルは変更として扱いたくない
- 過去の任意の期間を指定できるようにしたい
- スプレッドシートにコピペしたいので、出力はTSV形式にしたい
方法
以下のワンライナーで出力することができる
git log --name-only --oneline --diff-filter=M --since='1 year ago' | grep -v ' ' | sort | uniq -c | sort -nr | head -n 20 | sed 's/^[ ]*//' | tr ' ' '\t'
基本的には、Gitで更新頻度の高いファイルを見つける方法 - アジャイルSEの憂鬱 を参考にさせてもらいながら、特定の期間を指定したり、追加や削除やリネームされたファイルは含まず変更されたファイルのみを出力できるようにしました。
GitHub - spring-projects/spring-framework: Spring Framework に対して実行した結果は以下。
$ git log --name-only --oneline --diff-filter=M --since='1 year ago' | grep -v ' ' | sort | uniq -c | sort -nr | head -n 20 | sed 's/^[ ]*//' | tr ' ' '\t' 79 build.gradle 16 src/docs/asciidoc/testing.adoc 12 spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java 12 spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java 11 src/docs/asciidoc/data-access.adoc 11 spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java 9 src/docs/asciidoc/web/webflux.adoc 9 gradle/docs.gradle 8 src/docs/asciidoc/web/webmvc.adoc 8 src/docs/asciidoc/web/webflux-webclient.adoc 8 spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java 8 spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java 8 ci/pipeline.yml 7 src/docs/asciidoc/languages/kotlin.adoc 7 spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java 7 spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java 7 spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java 7 spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java 7 spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java 7 spring-test/src/main/java/org/springframework/test/context/NestedTestConfiguration.java
説明
git log --name-only --oneline --diff-filter=M --since='1 year ago'
過去1年分のコミットログから、ファイルが変更されたコミットのハッシュとコミットメッセージと修正されたファイル名のみ抽出している。--diff-filter
は指定する文字によって出力するファイルの差分をフィルタリングできるオプションで、例えば、--diff-filter=A
を指定すれば、追加されたファイルのみを出力できるし、--diff-filter=D
を指定すれば削除されたファイルのみを出力できる。--diff-filter=AD
のように複数指定することもできる。指定できる値の詳細は、Git - git-diff Documentation に書いてある。 また、期間の指定には--since
を使っているが、--after
や--before
などで期間を指定することもできる。grep -v ' '
コミットのハッシュとコミットメッセージを除去して、修正されたファイル名のみ抽出sort | uniq -c
uniq
でファイル名の重複を削除したいので、その前にsort
で、修正されたファイル名をソートし、その後uniq -c
でソートされたファイル名から重複を削除して、重複のカウントとファイル名を抽出sort -nr
文字列を数値として、降順にソートして出力head -n 20
先頭から20ファイルを抽出sed 's/^[ ]*//' | tr ' ' '\t'
先頭の空白文字を削除したり、TSV出力するため、文字列中の変更回数とファイル名の区切りを空白文字からタブ文字に変換