移行プロジェクトを進める前に、現状のコード量を解析したいと考えている。何かいい方法はないかなと思い、全ての答えが詰まっているTwitterで検索したところ、次のツイートを見つけた。
git diff --stat `git hash-object -t tree /dev/null` とかいうレポジトリの中のコードの行数を数える小技
— Hideyuki Tanaka (@tanakh) 2015年6月24日
実際に自分のサンドボックス用リポジトリで試してみた。確かにコード行数が出力される。
$ 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コマンド、色々知っていれば組み合わせて応用できるんだなと思った。
参考文献
- https://git-scm.com/docs/git-diff
- https://www.atlassian.com/ja/git/tutorials/saving-changes/git-diff
- https://qiita.com/shibukk/items/8c9362a5bd399b9c56be
- https://git-scm.com/docs/git-hash-object
- https://learning.oreilly.com/library/view/security-power-tools/9780596009632/ch16.html#:-:text=%2Fdev%2Fnull%20is,file%20or%20email
- https://learning.oreilly.com/library/view/a-practical-guide/9780768681406/ch07.html#:-:text=The%20%2Fdev%2Fnull,without%20a%20trace%3A
- https://learning.oreilly.com/library/view/linux-pocket-guide/9780596806347/ch01s01s03.html#:-:text=Options%20are%20not,for%20%E2%80%9Crun%20silently.%E2%80%9D
- https://learning.oreilly.com/answers/results/?question=How+to+count+code+lines&page=5
- https://github.com/AlDanial/cloc#install-via-package-manager
- https://www.npmjs.com/package/cloc
- https://qiita.com/gotchane/items/ef69af260c40fa26d78b
- https://www.r-staffing.co.jp/engineer/entry/20200605_1