QAチームのいさな(@isanasan_)です。今回は筆者のお気に入りのツールをご紹介します。
モチベーション
先週コードレビューについての記事を書きました。
ジョインから1ヶ月経ちコードレビューで気を付けていることをまとめた
こちらの記事の中でrebaseを使ってコミットログを整形することがレビューコストの低下に繋がると書きました。
しかし筆者はgitをcli上で使いこなすのはそれなりに難しいものだと感じており、特にinteractive rebaseは初学者にとって非常にとっつきにくい機能だと思っています。
そこで、今回は筆者が愛用しているgitのクライアントツールであるlazygitを紹介します。本稿ではハンズオン形式でgitの歴史改変の操作を説明していきます。尚、ハンズオンの題材に使ったコードは動作確認などはしていません。本題とは関係ないので細かいツッコミは無しでお願いします。
##環境
尚、筆者の環境は以下の通りです。
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から開くことが出来ます。
- Statusパネルに移動
-
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";
}
}
ステージングとコミット
作成したファイルを下記の手順でステージングしてコミットします。
- 対象のファイルを選択
spaceを押下してファイルをステージングcを押下してコミットメッセージの入力プロンプトを表示- コミットメッセージを入力
enterを押下してコミット
まずはファイルをコミットすることが出来ました。
typoを修正してamend commitする
コミットした後にタイポに気がついたので修正します。
- public function hallo()
+ public function hello()
ここで
fix: typo
なんていうコミットは積みたくないので下記の手順でamend commitします。
- 対象ファイルをステージング
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コミットを作ります。
- 変更内容をステージング
commitsパネルに移動- 修正対象のコミットにカーソルを合わせる
Fを押下してfixup commitを作成
fixupコミットを作ることが出来たので下記の手順でsquashして対象のコミットに変更を混ぜ込みます。
commitsパネルに移動- 対象のコミットにカーソルを合わせる
Sを押下してsquashを実行
履歴を遡ってコミットを修正することが出来ました。
remoteリポジトリを登録してpush
ここでリモートブランチにpushしてみましょう。
まずは下記の手順でリモートリポジトリを登録してpushします。今回はorigin git@github.com:isanasan/lazygit-tutorial.gitを登録します。
※ 事前にgithub上にリポジトリを作った上でremote urlをクリップボードからctrl-vでペーストしています
- Local Branchesパネルに移動
- Remoteタブに移動
nを押下- リモートの名称を入力して
enter - リモートのURLを入力して
enter
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を使ってコミットを整形してみます。
- それぞれのファイルを個別にコミットする
- rebaseの起点になるcommitを選択して
eを押下 - 混ぜ込みたいコミットを選択し
sを押下 - 混ぜ込みたいコミットを選択し
ctrl-jで対象のコミットの上に移動 mを押下してrebase optionを表示しcontinueを選択
とても簡単にinteractive rebaseすることが出来ました。
コミットメッセージを改変する
しかし、squashしたままだとコミットメッセージがおかしなことになっているので、下記の手順で修正していきます。
- 修正対象のコミットを選択して
Rを押下 - editorが起動するのでコミットメッセージを修正して
enterを押下
コミットメッセージを改変することが出来ました。
隣り合うコミットを一手でsquashする
履歴としてはこれでも問題ないのですが、コミットの粒度が細かすぎる気がするので
ec26f1d5と054b303bをsquashでまとめてしまいましょう。
squashしたいコミット同士が既に隣り合っている時はinteracrive rebaseを使うまでもなく下記の一手でsquashできます。
- 混ぜ込みたい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ブランチを作成します。
- Local Branchesに移動
Nを押下- ブランチ名を入力して
enterを押下
これで履歴を無視したブランチを作ることが出来ました。
orphanブランチでgit cleanを実行
リポジトリ内に存在しているファイルがステージング状態になっているので、下記の手順で全て削除します。
aを押下して全てのファイルのステージングを解除Dを押下してreset optionを表示git clean -fdを選択してuntracked filesを全て削除
これで真っ新なブランチが手に入りました。
orphanブランチにfirst commitを作る
真っ新なブランチが手に入ったのでfirst commitを作ります。readmeの追加とかでも良いのですが、このリポジトリはGitHubでpublicに公開するつもりなのでLISENCEファイルを作成してコミットすることにします。お好きなエディタでLICENSEファイルを作成してコミットします。
これでLICENSEファイルを追加するfirst commitを作ることが出来ました。
orphanブランチをリベースして取り込む
下記の手順でfirst commitを作ったorphanブランチをmainブランチに取り込みます。
- mainブランチにカーソルを合わせて
spaceを押下してswitch - Local Branchesパネルで対象のブランチにカーソルを合わせる
rを押下enterを押下してrebaseを実行
歴史を改変していとも簡単にfirst commitまで作成することが出来ました。
改めてsquashする
気をとりなおしてもう一度コミットの粒度を調整するためにsquashを実行します。対象同士が隣り合っているので下記の一手で出来ます。デモのgifではついでにRを使ってコミットメッセージの修正も行っています。
- 混ぜ込みたいコミットにカーソルを合わせて
sを押下
一手でsquashを実行し、コミットをまとめることが出来ました。
force pushする
禁じ手ですがforce pushして今までの作業を無かったことにします。
これで一通りの歴史改変作業は完了です。
マージして不要になったブランチを削除
ローカルに不要なブランチが残っているので下記の手順で削除しておきます。
- 対象のブランチにカーソルを合わせる
dを押下
これにて作業完了です。
まとめ
lazygitを使えばかなり簡単にgitの歴史改変が出来ることが分かって頂けたかと思います。
git操作苦手だよーっていう人は是非試してみてください。
参考
git コミットログを綺麗にしたい。fixupとsquash


















