コミットログを楽に整形できるlazygitの紹介

isanasan|2021年11月16日
ツール/ライブラリ

QAチームのいさな(@isanasan_)です。今回は筆者のお気に入りのツールをご紹介します。

モチベーション

先週コードレビューについての記事を書きました。
ジョインから1ヶ月経ちコードレビューで気を付けていることをまとめた

こちらの記事の中でrebaseを使ってコミットログを整形することがレビューコストの低下に繋がると書きました。
しかし筆者はgitをcli上で使いこなすのはそれなりに難しいものだと感じており、特にinteractive rebaseは初学者にとって非常にとっつきにくい機能だと思っています。

そこで、今回は筆者が愛用しているgitのクライアントツールであるlazygitを紹介します。本稿ではハンズオン形式でgitの歴史改変の操作を説明していきます。尚、ハンズオンの題材に使ったコードは動作確認などはしていません。本題とは関係ないので細かいツッコミは無しでお願いします。

##環境

尚、筆者の環境は以下の通りです。

– OS : windows10
– shell : powershell 7.2.0
– terminal : windows terminal
– git : 2.33.0.windows.2

lazygitとは

goで書かれたgitのTUIクライアントです。2021年11月現在のスター数は21.9kとかなりの人気OSSです。

GitHubリポジトリはこちら

インストール

早速インストールしてみましょう。基本的にメジャーなパッケージ管理ツールでinstall可能となっております。個人的には最新版のバイナリがすぐ取得できるgo installで入れるのが楽だと思います。
readmeを参考にお手元の環境に合わせた方法をご利用ください。

尚、本稿で扱うlazygitのバージョンは0.30.1です。

設定

windowsの場合、デフォルトだと選択中のカーソルにハイライトされなくて操作しようが無いので%APPDATA%\lazygit\config.ymlに下記設定をしておきます。

gui:
    theme:
        selectedLineBgColor:
            - reverse
        selectedRangeBgColor:
            - reverse

設定ファイルは下記の手順でlazygitから開くことが出来ます。

  1. Statusパネルに移動

  2. oを押下

最低限の操作方法

まずは最低限の操作方法を確認します。
コンソールを開いてlazygitと打てばlazygitが起動します。
適当なリポジトリで起動してみましょう。
移動に使うキーはh,j,k,l,[,]の6つです。

※ こちらの例ではlazygit自体のリポジトリでlazygitを起動しています

ハンズオン

それでは早速実際の作業を通してlazygitの使い方を見ていきましょう。
適当なディレクトリを切ってgit initしておきます。
まずはPeople.phpを作りましょう。

<?php

declare(strict_types=1);

class People
{
    public function hallo()
    {
        echo "hallo";
    }
}

ステージングとコミット

作成したファイルを下記の手順でステージングしてコミットします。

  1. 対象のファイルを選択
  2. spaceを押下してファイルをステージング
  3. cを押下してコミットメッセージの入力プロンプトを表示
  4. コミットメッセージを入力
  5. enterを押下してコミット

まずはファイルをコミットすることが出来ました。

typoを修正してamend commitする

コミットした後にタイポに気がついたので修正します。

- public function hallo()
+ public function hello()

ここで

fix: typo

なんていうコミットは積みたくないので下記の手順でamend commitします。

  1. 対象ファイルをステージング
  2. Aを押下してamend commit

これで無事不要なコミットを積むことなく修正を行うことが出来ました。

引き続き実装を進めていく

新しい仕様を思いついたので追加します。

- public function hello()
+ public function hello_to_name($name)

普通にステージングしてコミットします。

さらに先程のクラスを利用する側のコードを実装します。

index.php

require_once(dirname(__FILE__)."/People.php");

$mike = new People();

$mike->hello_to_name('john');

これで2つのファイルと3つのコミットが出来ました。

 

coding styleを修正してfixup commitする

index.phpをコミットした後にPeopleクラスのメソッド名がcamel caseになっていないことが気になったので修正します。

- public function hello_to_name($name)
+ public function helloToName($name)

ここでも

fix: coding style

みたいなコミットを積みたくは無いので下記の手順でfixupコミットを作ります。

  1. 変更内容をステージング
  2. commitsパネルに移動
  3. 修正対象のコミットにカーソルを合わせる
  4. Fを押下してfixup commitを作成

fixupコミットを作ることが出来たので下記の手順でsquashして対象のコミットに変更を混ぜ込みます。

  1. commitsパネルに移動
  2. 対象のコミットにカーソルを合わせる
  3. Sを押下してsquashを実行

履歴を遡ってコミットを修正することが出来ました。

remoteリポジトリを登録してpush

ここでリモートブランチにpushしてみましょう。
まずは下記の手順でリモートリポジトリを登録してpushします。今回はorigin git@github.com:isanasan/lazygit-tutorial.gitを登録します。
※ 事前にgithub上にリポジトリを作った上でremote urlをクリップボードからctrl-vでペーストしています

  1. Local Branchesパネルに移動
  2. Remoteタブに移動
  3. nを押下
  4. リモートの名称を入力してenter
  5. リモートのURLを入力してenter

  1. Pを押下してpush

リモートリポジトリを登録してpushすることが出来ました。

interactive rebaseを使って履歴を修正する

pushしてからこのままでは動かないことに素で気がついたので修正を加えます。

まずはindex.phpを編集します。

- $mike->hello_to_name('john');
+ $mike->helloToName('john');

ついでにhelloToNameメソッドの引数に型を付けます。

People.php

- public function helloToName($name)
+ public function helloToName(string $name)

先ほどと同様にfixupしても良いのですが、折角なのでinteractive rebaseを使ってコミットを整形してみます。

  1. それぞれのファイルを個別にコミットする
  2. rebaseの起点になるcommitを選択してeを押下
  3. 混ぜ込みたいコミットを選択しsを押下
  4. 混ぜ込みたいコミットを選択しctrl-jで対象のコミットの上に移動
  5. mを押下してrebase optionを表示しcontinueを選択

とても簡単にinteractive rebaseすることが出来ました。

コミットメッセージを改変する

しかし、squashしたままだとコミットメッセージがおかしなことになっているので、下記の手順で修正していきます。

  1. 修正対象のコミットを選択してRを押下
  2. editorが起動するのでコミットメッセージを修正してenterを押下

コミットメッセージを改変することが出来ました。

隣り合うコミットを一手でsquashする

履歴としてはこれでも問題ないのですが、コミットの粒度が細かすぎる気がするので
ec26f1d5054b303bをsquashでまとめてしまいましょう。
squashしたいコミット同士が既に隣り合っている時はinteracrive rebaseを使うまでもなく下記の一手でsquashできます。

  1. 混ぜ込みたいcommitにカーソルを合わせてsを押下

おっと、

You can not squash/fixup onto the second commit

と怒られてしまいました。最初のコミットにrebaseは実行できないのでした。

CustomCommandsを定義して更に高度な歴史改変をしてみる

仕方ないので更に歴史を改変してfirst commitを作りましょう。

first commitを後から追加するにはgit checkout --orphanコマンドを実行してorphanブランチを作る必要があるのですが、lazygitの標準の機能ではorphanブランチを作れないのでcustomCommandsを定義してやります。
%APPDATA%\lazygit\config.ymlに以下の定義を追加しlazygitを再起動します。

customCommands:
    - key: "N"
        prompts:
            - type: "input"
            title: "What is the new orphan branch name?"
            initialValue: ""
        command: "git checkout --orphan {{index .PromptResponses 0}}"
        context: "localBranches"
        loadingText: "creating orphan branch"

以下簡単に説明します。

key

custom commandを呼び出すkey bind。今回はorphanブランチを作成するコマンドを定義するので、通常のブランチ作成のkeyであるnに合わせてNとしておく。

prompts

custom command実行時に表示するインターフェースの設定項目です。1つのcustom commandに対して複数のpromptを設定することが出来ます。

type

promptの種類をinputもしくはmenuから選べます。今回はgit checkout --orphanの引数にブランチ名を入力したいのでinputを指定します。

title

promptの表示名称です。

initialValue

promptの初期値です。

command

呼び出したいコマンド。今回はgit checkout --orphan {{index .PromptResponses 0}}としてpromptの入力内容を引数として設定する。{{index .PromptResponses 0}}で何番目のpromptなのかを指定してやれば値を取れる仕組みとなっています。

context

custom commandを定義するpanelを指定する。今回はbranch操作に関連した設定なのでlocalBranchesを設定します。

loadingText

読み込み中の出力文字列。creating orphan branchとでもしておきます。

customCommandsの詳しい解説はこちらで確認できます。

定義したCustomCommandを使ってorphanブランチを作る

CustomCommandでgit chackout --orphanを使えるように設定したので下記の手順でorphanブランチを作成します。

  1. Local Branchesに移動
  2. Nを押下
  3. ブランチ名を入力してenterを押下

これで履歴を無視したブランチを作ることが出来ました。

orphanブランチでgit cleanを実行

リポジトリ内に存在しているファイルがステージング状態になっているので、下記の手順で全て削除します。

  1. aを押下して全てのファイルのステージングを解除
  2. Dを押下してreset optionを表示
  3. git clean -fdを選択してuntracked filesを全て削除

これで真っ新なブランチが手に入りました。

orphanブランチにfirst commitを作る

真っ新なブランチが手に入ったのでfirst commitを作ります。readmeの追加とかでも良いのですが、このリポジトリはGitHubでpublicに公開するつもりなのでLISENCEファイルを作成してコミットすることにします。お好きなエディタでLICENSEファイルを作成してコミットします。

これでLICENSEファイルを追加するfirst commitを作ることが出来ました。

orphanブランチをリベースして取り込む

下記の手順でfirst commitを作ったorphanブランチをmainブランチに取り込みます。

  1. mainブランチにカーソルを合わせてspaceを押下してswitch
  2. Local Branchesパネルで対象のブランチにカーソルを合わせる
  3. rを押下
  4. enterを押下してrebaseを実行

歴史を改変していとも簡単にfirst commitまで作成することが出来ました。

改めてsquashする

気をとりなおしてもう一度コミットの粒度を調整するためにsquashを実行します。対象同士が隣り合っているので下記の一手で出来ます。デモのgifではついでにRを使ってコミットメッセージの修正も行っています。

  1. 混ぜ込みたいコミットにカーソルを合わせてsを押下

一手でsquashを実行し、コミットをまとめることが出来ました。

force pushする

禁じ手ですがforce pushして今までの作業を無かったことにします。

これで一通りの歴史改変作業は完了です。

マージして不要になったブランチを削除

ローカルに不要なブランチが残っているので下記の手順で削除しておきます。

  1. 対象のブランチにカーソルを合わせる
  2. dを押下

これにて作業完了です。

まとめ

lazygitを使えばかなり簡単にgitの歴史改変が出来ることが分かって頂けたかと思います。

git操作苦手だよーっていう人は是非試してみてください。

参考

git コミットログを綺麗にしたい。fixupとsquash

余談1:  実は執筆当時の最新バージョンは0.31.3なのですが更新できていないことに気がついたのがgifを一通り撮影した後で今更やりなおすのは流石に厳しいという気持だったのでちょっと古いバージョンでの執筆になったのでした
余談2: 筆者はもうlazygit無しでgit操作をすることは出来ない体になってしまっています