【PHP】【Git】git logから時系列順でコードの量がどれくらい増えているかをCSVに出力する

 どれくらい複雑になってきているか何となく気になる時があります。そんな時にざっくり目安になるのが行数です。厳格な複雑度の指標としては心もとない情報ですが、なんとなくどんな勢いで複雑になってきているかを感じるならこれぐらいで足ります。この記事ではGitのログからコードの総量の変化を知る方法を紹介します。

 実際のコードが次です。これをGitリポジトリのあるディレクトリで実行すればgit logの結果を元に日ごとのコードの総量を記録したtmp.tsvファイルが出力されます。

<?php

// ファイルの末尾が指定した文字列で終わっているかチェックするための配列
$whiteListExtensions = ['.php', '.ts', '.tsx', '.scss', '.sh', '.json'];
// ファイルの末尾が指定した文字列以外で終わっているかチェックするための配列
$blackListExtensions = ['composer.json', 'package.json','package-lock.json'];

// git log コマンドを実行して、時系列昇順で行の増減を出力
$log_data = shell_exec('git log --pretty="format:%H %ad" --date=short --numstat --reverse');

// 変数初期化
$lines        = explode("\n", $log_data);
$commit_data  = [];
$current_date = "";
$total_lines  = 0;

// ログデータをパース
foreach ($lines as $line) {
    // 行を整えて空行ならスキップ
    $line = trim($line);
    if (empty($line)) {
        continue;
    }

    // コミット行(ハッシュと日付を含む)
    if (preg_match('/^[a-f0-9]{40} \d{4}-\d{2}-\d{2}$/', $line)) {
        list($commit_hash, $commit_date) = explode(" ", $line);
        $current_date = $commit_date;

        // コミットの日付ごとにデータを初期化(新規の日付が見つかった場合)
        if (!isset($commit_data[$current_date])) {
            $commit_data[$current_date] = $total_lines;
        }
    } // ファイルの行数の増減を表す行
    elseif (preg_match('/^(\d+|-)\s+(\d+|-)\s+/', $line, $matches)) {
        if ($whiteListExtensions) {
            // ファイルの末尾がホワイトリストに含まれているかチェック
            // 全く含まれていなかったらスキップ
            $exists = false;
            foreach ($whiteListExtensions as $ext) {
                $exists = $exists || str_ends_with($line, $ext);
            }
            if (!$exists) {
                continue;
            }
        }
        if($blackListExtensions){
            // ファイルの末尾がブラックリストに含まれているかチェック
            // 一つでも含まれていたらスキップ
            foreach ($blackListExtensions as $ext) {
                if (str_ends_with($line, $ext)) {
                    continue 2;
                }
            }
        }
        // 行数の増減を取得
        $added_lines   = $matches[1] === '-' ? 0 : (int)$matches[1];
        $deleted_lines = $matches[2] === '-' ? 0 : (int)$matches[2];
        // 合計行数を更新
        $total_lines += $added_lines - $deleted_lines;
        // 日付ごとの累積行数を更新
        $commit_data[$current_date] = $total_lines;
    }
}

// TSVファイルに出力
$output_file = 'tmp.code_quantity_over_time.tsv';
$fp          = fopen($output_file, 'w');

// ヘッダーの書き込み
fputcsv($fp, ['日付', '行数'], "\t");

// データの書き込み
foreach ($commit_data as $date => $line_count) {
    fputcsv($fp, [$date, $line_count], "\t");
}

fclose($fp);
echo "TSVファイルに出力しました: {$output_file}\n";

 これで次のようなファイルができ、

日付	行数
2022/3/14	42879
2022/3/15	44999
2022/3/16	50779
2022/3/18	50902
2022/3/21	50970
2022/3/28	50141

 Excelなりスプレッドシートなりでコード量と日付の次のようなグラフを見れます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG