コード行数を数えたい

移行プロジェクトを進める前に、現状のコード量を解析したいと考えている。何かいい方法はないかなと思い、全ての答えが詰まっているTwitterで検索したところ、次のツイートを見つけた。

実際に自分のサンドボックス用リポジトリで試してみた。確かにコード行数が出力される。

$ git diff --stat `git hash-object -t tree /dev/null`
# 色々省略している
 src/setupTests.ts                    |     5 +
 src/stories/Button.jsx               |    50 +
 src/stories/Button.stories.jsx       |    40 +
 src/stories/Header.jsx               |    57 +

なぜこうなるのかなと思い、少し調べてみた。

git diff

変更の差分を見るコマンドと理解していた。git diff --statだとファイルのdiffがどのくらいあるか、という観点で確認できる。

Gitのドキュメントで--statオプションについて確認すると次のような記載がある。

--stat[=<width>[,<name-width>[,<count>]]]

By giving a third parameter , you can limit the output to the first lines, followed by ... if there are more.

--statオプションにcount対象を引数に入れると行数を数えてくれる。git hash-object -t tree /dev/nullの部分がcount対象ということになる。

git hash-object

これはblob(gitにファイルを保存するためのオブジェクト)のハッシュIDを取り出すためのコマンドである。-tオプションでIDを取り出す対象を指定できる。

tree /dev/null

データを送信すると消える領域のこと。tree /dev/nullでデータを消す領域のツリー構造を出している。

つまりどういうこと

git diff --stat `git hash-object -t tree /dev/null`

データがない領域のハッシュIDを指定(=つまり何もない場所)とのファイル行数の差分を出している。

他の手段はあるの

wc -lコマンドを使ってもファイルの行数を確認できる。しかし、こちらはディレクトリを再起的に辿ることができない。git diffは変更の差分にフォーカスできるので、ディレクトリ構造が複雑な場合はgit diffを使った方が良いなと思った。

特定の拡張子だけ数えられないの

特定の拡張子のファイルを数えるなら、lsコマンドで数えたいファイル名を出力し、パイプでwc -lをつなげ、lsした結果を数える手段もある。

# cssファイルのみ数えたい
ls -al src/*.css | wc -l

しかし、なんやかんやでclocを使う方が便利かもしれない。npmパッケージとしても登録されているし。

$ npx cloc src/*
      28 text files.
      28 unique files.                              
       0 files ignored.

github.com/AlDanial/cloc v 1.96  T=0.04 s (689.1 files/s, 19172.6 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
JSX                              6             28             25            212
Markdown                         1             22              0            189
CSS                              6             19              0            170
TypeScript                       7             10              8             88
SVG                              8              0              0              8
-------------------------------------------------------------------------------
SUM:                            28             79             33            667
-------------------------------------------------------------------------------

特定の文字列が含まれているコード数を抽出できないの

特定の文字列が含まれるコード数を検索する場合、git grepで対象の行をgrepし、パイプでwc -lを繋げてgrep行数を数える手段が良さそう。

# `button`が含まれるコード数を数えたい
$ git grep button | wc -l
      15

まとめ

  • Gitリポジトリで管理されているコード行数はgitコマンドを使うと効率良く数えられる

GitコマンドとLinuxコマンド、色々知っていれば組み合わせて応用できるんだなと思った。

参考文献