CreateField Blog

オープンソースを使って個人でWebサービスを開発・運営していたブログ

Gitブランチの総滞在時間を使ってタスク毎の総作業時間を計算する

はじめに

開発現場ではRedmineやBacklogなどチケット管理システムを使ってタスク管理することがよくあると思います。

ただ、一挙手一投足で作業時間をタイマーで図るといったことは手間ですし、そういったルールには不満もでるかと思います。

そこで、タスクの作業実績時間を管理するために、極力新たな手間をかけずに時間を計算できないかと検討したところ、Gitのブランチの滞在時間=タスク時間とざっくりみなすのはどうかと考えました。

私の感覚では、Gitのコミット単位ですと粒度的には細かすぎますが、Gitのブランチとチケットであれば、対応づけるのにちょうどいいサイズかなという感覚です。

ローカル単位ですので、レビュアーのチェック時間もこれで推定することができそうです。

運用ルール

Gitコマンドではreflogを使うことによってチェックアウトのブランチ移動時間を取得することができますので、新たに時間計測ツール等を導入しなくとも、以下を運用ルールとすれば、ざっくりとしたタスク毎の作業時間の計測が可能になります。

  • タスク単位でブランチを切って、タスク作業中はブランチに滞在すること
  • 日を跨ぐ作業など、作業から長時間離れる場合はmasterや一時的に子ブランチを作って作業ブランチから移動すること

1点目は、タスク単位でブランチを切るのはチーム開発では、普通に行われることだと思いますので、さほど適用にハードルはなさそうです。

2点目は、作業ブランチにいる=作業中であるということを意識づけることにより、メリハリがつくメリットがありそうです(かもしれません)。

ただ、今の所、ちょっとした離席などは、あまり厳密にやりすぎないほうがいいのかなと考えています。

ブランチの総滞在時間計算スクリプト

上記のような運用ルールを守ってブランチに滞在するようにしておけば、例えば、Gitコマンドのreflogから以下のスクリプトのようにブランチ毎の総滞在時間を簡単に計算することができます。

#!/bin/bash

# License: Public domain.
# You can copy and modify this script freely.

reflog=$(git reflog --date=iso --pretty='%gd %gs' --date=format:'%Y-%m-%d %H:%M:%S' | grep checkout:)

branch_times=""
branch_dates=""
last_line=""
while read line
do
  if [ "$last_line" != "" ]; then
    set ${line}

    datetime="$(echo ${1} | cut -b 7-16) $(echo ${2} | cut -b 1-8)"
    from=${6}
    to=${8}

    set ${last_line}
    last_datetime="$(echo ${1} | cut -b 7-16) $(echo ${2} | cut -b 1-8)"
    last_from=${6}
    last_to=${8}

    if [ $last_from = $to ] && [ $to != "master" ]; then
      last_date="$(echo ${last_datetime} | cut -b 1-10)"
      if [ "$(uname)" == 'Darwin' ]; then
        elapsed_sec=$(expr `date -j -f "%Y-%m-%d %H:%M:%S" "${last_datetime}" +%s` - `date -j -f "%Y-%m-%d %H:%M:%S" "${datetime}" +%s`)
      else
        elapsed_sec=$(expr `date -d"${last_datetime}" +%s` - `date -d"${datetime}" +%s`)
      fi
      elapsed_hour="$(awk "BEGIN {print ${elapsed_sec}/3600}")"
      branch_times="${branch_times} ${to} ${elapsed_hour}"
      branch_dates="${branch_dates} ${to} ${last_date}"
    fi
  fi
  last_line=${line}
done < <(echo "$reflog")

if [ "${branch_times}" != "" ]; then
read -d '' scriptVar << EOF
BEGIN {
  times_length = split("${branch_times}", times, " ");
  split("${branch_dates}", dates, " ");
  split("", counter);
  for (i = times_length; i > 0; i--) {
    if (i % 2 == 0) {
      counter[times[i-1]] += times[i];
      branches[dates[i-1]] = dates[i];
    }
  }
  for (i in counter) {
    print branches[i]" "i" "counter[i]
  }
}
EOF
fi

awk "$scriptVar" | sort
% bash  git_branch_time_calc.sh
...
2020-08-17 work-group-default 1.59944
2020-08-24 excel-macro 2.71694
...

git reflogの保持期間

git reflogの保持期間はデフォルトでは、90日となっています。 以下のコマンドを設定しておけば、個別設定がなければ無制限とすることも可能です。

git config --global gc.reflogExpire never

長時間離席時

長時間離席時は以下のように、作業ブランチの子ブランチを作って移動するか、コミットしておいてmasterに戻っておくようにします。

#作業中断時
git checkout -b tmp

#作業再開時
git checkout work-branch && git branch -D tmp
#作業中断時
git add ./*
Git commit -m "tmp"
Git checkout master

#作業再開時
Git checkout work-branch
Git reset HEAD^