Termina上でGitのログ表示を最高に見やすくするTUIアプリ「gitone」を作った

![gitone-light-demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/7b308c67-65e1-c527-4448-e01972d9f9b4.gif)

Gitプロジェクト上で `gitone` と打つとGitのログをグラフ表示してくれる大変シンプルなアプリです。そのままカーソル行を動かしていくと簡易な情報が常に下のステータスバーに表示されていて、Enterで選択するとさらに詳細なGit showをlessで見ることができるようになっています。

Go言語で作られていて、macOSでもLinuxでも、そしてWindowsでも使うことができちゃいます！

この記事では、最初の方にこのアプリのコンセプトと使い方、そして最後に技術的な話をしていきたいと思います。

Githubのリンクはこちらです。
<a href="https://github.com/yasukotelin/gitone"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/yasukotelin/gitone.png" width="460px"></a>

## コンセプト

僕は普段Gitの操作はコマンドを使っていてGUIなツールは特に使っていません。基本的にそれで不満もないですし、頻繁にいろいろなリポジトリを移動するので大変相性がいいです。

しかし、1点、普段使いしていてとても不便な部分がありました。それがログのグラフ表示です。ツリー表示とも言うんですかね。GUIアプリのGitクライアントを使っているメリットもここにあるでしょう。グラフ表示されていると、Gitのログ状態が視覚的にわかって大変便利ですし、心理的安全性もあります。そのプロジェクトを触る人が多くなればなるほど、プロジェクトのツリー状態がどうなっているかが見たくなるでしょう。そう言う時Gitのコマンドだけだとなかなか不便でした。

そこで、Gitのlogコマンドのオプションをカスタマイズして簡易的に見れるようにaliasを作って使っていました。

```
[alias]
    tree = log --graph --all --pretty=format:'%C(bold blue)%h%Creset -%C(magenta)%d%Creset %s %C(yellow)(%cd) %C(cyan)<%an>%Creset' --abbrev-commit --date=iso-local
```

このaliasを `.gitconfig` ファイルに記載して `git tree` と打つとこんな感じでグラフ表示がされます。

![スクリーンショット 2020-02-01 19.19.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/95ce6f99-7039-7291-0692-513e372ea54e.png)

今までずっとこのコマンドを使っていましたが、この表示方法にはいくつか欠点があります。
- 詳細な情報を見たい場合にいちいちコミット番号をコピーして `git show <commit番号>` する必要があった
- Terminalのサイズが小さい場合やグラフが大きい場合に改行が発生して大変見辛いことがある

この2点があります。僕はTerminalをあまり最大表示にして使わないのですが、グラフが非常に大きくなると改行が発生してもうめちゃくちゃな表示になってしまいます。こんな感じで。

![スクリーンショット 2020-02-01 19.23.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/eb6a9e39-e356-823a-7ec1-bb70879b1127.png)

さて、話は変わって、[tig](https://github.com/jonas/tig)と言う有名なGitクライアントがあります。これもTUIアプリで、Terminal上で動作する非常に強い、多機能なアプリです。これは本当によくできていて、情報が多くても扱えるようにデザインされています。
ただ、個人的には、Gitの操作は基本的にコマンドを使いたい、グラフ表示だけでいい、と言うスタイルにはちょっと多機能すぎました。そしてグラフ表示もちょっと見辛い。

![スクリーンショット 2020-02-01 19.26.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/3c32d48e-6feb-d0ed-0492-fde35cc7dc0f.png)

で、次に着目したのが[GitUp](https://github.com/git-up/GitUp)と言うmacOS専用のGUIクライアントです。
非常に軽快に動作して、その分表示がとてもシンプル。基本的にはグラフだけが描画されていて、コミットの点をマウスでホバーするか移動した時だけ情報が出てくると言うデザインでした。

![687474703a2f2f692e696d6775722e636f6d2f743669433954432e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/ef920c06-b8c9-7285-5184-c0dd9696630e.png)
(https://github.com/git-up/GitUp）

そこで閃いたのがgitoneです。
- 軽量にグラフ表示だけがされるデザイン
- コミットの点を選択すると簡易な情報が表示される
- さらにEnterか何かを押すとそのコミットの `git show` 表示を見ることができる
- グラフ表示だけのシンプルなUIにして、Terminalの幅が小さくても、グラフが大きくても見やすくする

そして実際に作られたものがどんな感じなのかはこの記事の最初のGif動画をご覧ください。笑

gitoneはあくまでもGitのグラフ表示をするツールです。tigの場合はTerminal上で動作するGitのクライアントアプリですが、このgitoneはいわゆるGitのクライアントアプリではありません。

Gitの操作は今まで通りコマンドでカタカタして、ツリー表示が確認したくなったら `gitone` で確認できる。そう言うアプリを作ってみました。

## インストール

このアプリはGo言語で作られているので、Goさえインストールされていれば簡単にインストールができます。

### go getを使う方法

このアプリはGoモジュールを使って実装しているので、GoモジュールをONにしてgo getする必要があります。

```
GO111MODULE=on go get -u github.com/yasukotelin/gitone
```

これだけ。アップデートの時も同様に上のコマンドを打てばアップデートされます。

### git cloneしてインストールする方法

ソースコードをcloneしてインストールも可能です。Goモジュールがどうのとか、GO111MODULE=onとかがよくわからなければこちらの方法がおすすめです。

```
git clone https://github.com/yasukotelin/gitone.git
cd gitone
go install
```

gitoneのインストールはこれで完了です。

あと、git showコマンドなどの結果を閲覧するためにlessを使っています。macoSやLinuxの場合は特に意識しなくてもlessはインストール済みだと思います。Windowsの場合も、gitbashの場合はlessがあるので特に何もしなくても大丈夫です。gitbashインストール時にlinuxコマンドをコマンドプロンプトでも使えるようにする設定でインストールしている場合はコマンドプロンプトからも使えるはずですが、そうでない場合は別途lessのインストールもしてください。

## 使い方

使い方はとっても簡単！！Gitのプロジェクトパスないでgitoneを起動するだけです。

```
gitone
```

Windowsのgit bashを使っている場合は先頭に `winpty` をつけて実行してください。

```
winpty gitone
```

### 操作方法

矢印キーでの移動にプラスして、lessとかVimライクなキーバインドも用意してみました。操作の感じはこんな感じです。

| Key1         | Key2     | Motion                                          |
|--------------|----------|-------------------------------------------------|
| Enter        | Space    | カーソル行上のgit show表示        |
| Ctrl + Space |          | カーソル行上のgit show --stat表示 |
| q            | Ctrl + c | gitoneの終了                  |
| q            |          | less起動時はlessを終了してgitoneに戻る        |
| Down key     | j        | カーソル行を下に1移動                                     |
| Up key       | k        | カーソル行を上に1移動                                       |
| Home key     | g        | 先頭行にジャンプ                                |
| End key      | G        | 最終行にジャンプ                             |
| PgDn key     | Ctrl + d | カーソル行を下に5行移動                                  |
| pgUp key     | Ctrl + u | カーソル行を上に5行移動                                    |

機能としては、現段階では矢印で移動して確認するだけなのでとっても簡単です。詳細をみたくなったらEnterです。

Ctrl+Spaceを押すと、stat表示と言って、編集されたファイルの一覧表示がされます。俯瞰したい時に便利！

### Theme

ターミナルの背景色に関わらずデフォルトは黒背景な感じで起動するようになっています。ですが、私自身も白背景のターミナルを愛用していますし、黒背景だといやだ！と言う人も多いはず。

そこでいくつかテーマを用意しました。起動時に指定してあげるとカラーを変更できます。毎回指定するのは不便だと思うので僕はaliasに登録しています。

ちなみに、こう言う色合いが欲しい！などの要望があればIssueにいただければ追加します。あるいは、割と簡単に追加できるはずなので、PRお待ちしてます。笑

### dark (デフォルト）

```
gitone --theme=dark
```

![gitone-dark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/126bb021-429e-5ca0-eaaa-f778325a12fe.png)


### light

```
gitone --theme=light
```

![gitone-light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/9f6f6c32-442a-d72f-200e-bdf80e98e193.png)


### solid dark

使っているTerminalの色合いによってはdarkでもlightでも使いにくい場合があります。その場合はこのsolidを使ってください。

```
gitone --theme=soliddark
```

![gitone-soliddark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/3dad9760-4b0c-fba5-7e22-c4906b44af4a.png)


### solid light

```
gitone --theme=solidlight
```

![gitone-solidlight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166629/cd1ae11c-888b-b3dd-3fdd-510481b78026.png)

## 技術的な話

gitoneはGo言語で書かれています。Go言語はこう言うTUIアプリを簡単に作れるようなライブラリが多数あって、このgitoneもそれを使って書いているのでそれほど大したことはしていません。

ただ、TUIライブラリの選定に結構時間がかかりました。。今回使っているのはtviewと言うライブラリなのですが、他にもここら辺も選定してました。

- [marcusolsson/tui-go](https://github.com/marcusolsson/tui-go)
- [gizak/termui](https://github.com/gizak/termui)
- [nsf/termbox-go](https://github.com/nsf/termbox-go)
- [rivo/tview](https://github.com/rivo/tview)

他にも色々彷徨った記憶があります。笑　色々ライブラリがあるのですが、今回自分が作りたいツール的に、簡単に描画ができて行選択ができる、と言うような部分で選定しました。

そして、白背景のターミナルでも使える、と言う部分も重要でした。今回使っているtviewはとても使いやすくて非常によくできていたのですが、黒背景のターミナルを前提にしているようで、残念ながら白背景のターミナルで普通に使うと表示が崩れます。特にボーダーを使うと上手く描画されなくて、このライブラリを使って実装されている有名なTUIアプリもやはり表示に難があります。

tviewはターミナルの背景からよしなに色描画はしてくれませんが、アプリの背景色にwhiteを設定して、ボーダーを使わなければいい感じで表示されることに気付きました。

gitoneはいろいろな環境で表示できるように、ボーダーなどの描画が怪しい要素は使っていません。そして、背景色に合わせる案としてthemeと言うオプションを追加してみました。ANSIカラーを使っているので青や緑の色はターミナルに設定されている値が使われますが、これもユーザーの設定によっては薄い緑に白で文字が全く見えないと言うことが発生します。そこでsolidテーマも追加してみました。

今のところ4種類のテーマしかありませんが、箇所ごとに色設定できるようなソースコードになっているので簡単に追加できます。issueとプルリクお待ちしてます。笑

あとは、gitoneではgit showをlessで表示しています。Gitの標準でもlessを使って表示されていると思いますが、わざわざ別途lessにパイプしています。

```
git show --color=always | less -R
```

show表示は情報量が多いのでlessで表示できると検索などもできてとても便利なのでそうしています。

tviewを一時的にサスペンドしていてlessを抜けるとgitone側に戻る、と言うような挙動にしているのですが、git showの標準のlessは、ターミナルの領域よりも行数が多い時だけ使われて、行数が少ない時はそのまま標準出力されてしまいます。また、less表示したとしてもターミナルにlessの内容が出力されると言う仕様のため、あえてlessにパイプして表示することで行数が少なくてもlessが使われるようにし、ターミナルにも内容が出力されないようにしました。

また、git showはパイプしてlessに渡すと色の情報は載せない、と言う挙動をします。そこで `git show --color=always` で常にカラーコードを含んで出力するようにしています。less側も `less -R` とすることでカラーコードを着色して表示するようにしています。

## おわり

2月から新天地に転職するので有給消化をしているのですが、次職の勉強をしている時にこのgitoneのアイデアを思いつきました。最後の数日はこのgitoneを作っていてそっちの勉強がおざなりになったのが非常に心配なのですが、このgitoneを使って、新天地でのチーム開発に役立てられたらなと思います（笑）

あと、ツール公開と同時にTwitterで宣伝したのですが、ものの数分で@gorilla0513さんからPRもらいました。その他も色々アドバイスももらえて、OSSってやっぱりいいなと思いましたので、ここに感謝の意を残しておきます。ありがとうございます！