タグごとのコミット数を一覧で表示する

花粉がほんま辛い。

開発環境

> sh --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20)
Copyright (C) 2007 Free Software Foundation, Inc.

> git --version
git version 2.33.1

作ったもの

f:id:tokizuoh:20220319192510p:plain

> sh ./test.sh
From git@github.com:tokizuoh/faaaar.git

---
Aggregated the number of commits for 4 tags.
---
refs/tags/0.1          :    5 (+5) 
refs/tags/0.2          :  158 (+153) 
refs/tags/0.3          :  224 (+66) 
refs/tags/0.3-20220311 :  226 (+2) 

タグごとのコミット数を一覧で表示する。
「このタグのコミット増加数多いやん/少ないやん」みたいなことが分かって楽しい。

モチベーション

書籍「Clean Architecture 達人に学ぶソフトウェアの構造と設計)」の第1章で、リリースあたりのコード増加量の話が出てくる。
それを見て、タグごとのコミット数の差分が見れたらおもろいんじゃないかと思って作った。

コード

#!/bin/sh

# "{コミットハッシュ} {タグ名}" のパターンで配列に代入
array=(`git ls-remote --tags`)

tags=()
commits=()
diffs=()

previous_count=0
max_tag_length=0
max_commit_nod=0  # number_of_degits

for ((i=0;i<${#array[@]};i+=2))
do
    index=$((i/2))

    # タグ名
    tag=${array[i+1]}
    tags[$index]=$tag

    tag_length=${#tag}
    if [ $tag_length -gt $max_tag_length ]; then
        max_tag_length=$tag_length
    fi
    
    # 今見てるタグのコミット数
    commit_count=`git rev-list --count $tag`
    commits[$index]=$commit_count
    
    commit_nod=${#commit_count}
    if [ $commit_nod -gt $max_commit_nod ]; then
        max_commit_nod=$commit_nod
    fi
    
    # {今見てるタグのコミット数} - {一つ前のタグのコミット数}
    diffs[$index]=$((commit_count-previous_count))
    previous_count=$commit_count
done

# 出力
tag_count=${#tags[@]}

echo ""
echo "---"
echo "Aggregated the number of commits for $tag_count tags."
echo "---"

for ((i=0;i<${#tags[@]};i++))
do
    tag=${tags[i]}
    tag_length=${#tags[i]}
    commit_count=${commits[i]}
    commit_nod=${#commit_count}
    diff=${diffs[i]}
    printf "$tag%$((max_tag_length-tag_length))s : %$((max_commit_nod-commit_nod))s $commit_count (+$diff) \n"
done

書き終わった後に「なんでシェルスクリプトで書いたんだ?」という疑問が浮かんだ。なかなか綺麗に書けない。

参考