CUIで見やすい git コミットグラフ: git-foresta 作った

# なぜ作ったか
ターミナルでの git 操作に [tig](https://github.com/jonas/tig) を愛用してます。素晴らしいツールなんですが、マージが入り組んでくるとコミットグラフの線が途切れてしまったり、結構見るのがしんどくなります。tig と併用する目的で、入り組んだマージ履歴を見やすく表示可能な、テキストベースのコミットグラフ表示ツールを探していました。

そんな時、 Jan Engelhardt 氏が作った [git-forest](http://inai.de/projects/hxtools/) を見つけました。入り組んだマージ履歴も見やすく表示できるコミットグラフはいい感じなんですが、ハッシュ・日付・作成者・ブランチ名などの表示方式がイマイチに感じ、コードをいじっているうちに元とは結構違う見た目になりました。これを周囲の人にも使ってもらったところ「見やすい」と評判が良く、せっかくなので公開することにしました。

# サンプル（スクリーンショット）
というわけで、さっそくサンプルをご覧ください。まず `git-foresta --all --style=10 | less -RSX` の実行結果を [Meslo LG](https://github.com/andreberg/Meslo-Font) フォントで表示したものが下のスクリーンショットです。

![zzz_git-forest-sample1.png](https://qiita-image-store.s3.amazonaws.com/0/48289/f7d6527b-9fd3-4b22-c3c6-0e8447d4c9ab.png)

次は別パターン、 `git-foresta --all --style=1 --graph-symbol-commit=★ --graph-symbol-tip=☆ --graph-margin-right=2 | less -RSX` の実行結果を[Ricty Diminished](https://github.com/edihbrandon/RictyDiminished) フォントで表示したものが下のスクリーンショットです。

![zzz_git-forest-sample2.png](https://qiita-image-store.s3.amazonaws.com/0/48289/c0248315-532c-d986-0c2c-e3c4aebb32f7.png)

なお、上記2つともターミナルエミュレータとして [iTerm2](https://www.iterm2.com/) に [Solarized Dark](https://github.com/altercation/solarized/tree/master/iterm2-colors-solarized) カラースキームを適用したものを使っています。

# 使い方
`git-foresta` コマンドは `git log` と同様の引数・オプションを受け付けます（ただし `--pretty` と `--format` を除く）。それに加えて、以下のオプションも受け付けます。

* `--help`: 使い方のヘルプを表示して終了します。
* `--svdepth=<Subvine depth>`: ブランチ同士を結ぶ中間線（`┘`と`┌`の間など）の最大長（デフォルト: `2`）。  
  これを超える線は外側に回り込みます。
* `--no-status`: ワーキングツリーの状態を HEAD の近くに表示しない（デフォルトでは表示する）。
* `--style=<Style>`: コミットグラフの線のスタイルを以下から選んで `<Style>` に指定します。
  - `1`: 普通の線（デフォルト）
  - `2`: 二重線
  - `10`: 角の丸い線（Unicodeに対応したフォントが必要です）
  - `15`: 太線
* `--graph-margin-left=<Margin>`: コミットグラフの左の余白（デフォルト: `2`）。
* `--graph-margin-right=<Margin>`: コミットグラフの右の余白（デフォルト: `1`）。
* `--graph-symbol-commit=<Symbol>`: グラフでコミットを表すシンボル（デフォルト: `●` ）。
* `--graph-symbol-merge=<Symbol>`: グラフでマージを表すシンボル（デフォルト: `◎` ）。
* `--graph-symbol-overpass=<Symbol>`: グラフで飛び越しを表すシンボル（デフォルト: `═` ）。
* `--graph-symbol-root=<Symbol>`: グラフで根元を表すシンボル（デフォルト: `■` ）。
* `--graph-symbol-tip=<Symbol>`: グラフで先端を表すシンボル（デフォルト: `○` ）。
* `--version`: バージョンを表示して終了します。

その他の全ての引数とオプション（`--pretty`及び`--format`以外）は内部的に git-log コマンドに渡されます（`--all` や `--topo-order` など）。

なお、 git-foresta は自身でページャを持っていないため、他のページャ機能を持つプログラムに適切なオプションとともにパイプで渡して表示するとよいでしょう(例： `git-foresta | less -RSX`)。

# 入手先
GitHub で公開しています → https://github.com/takaaki-kasai/git-foresta
ライセンスは GPL-3.0 です。

# インストール方法
前述の入手先からソースコードをアーカイブでダウンロードするか git clone や curl 等で入手後、 リポジトリのルートディレクトリにある `git-foresta` ファイルを PATH の通った場所にコピーし、実行権限を付与するだけです（Mac・Linux・Windows + Git Bash で動作を確認済みですが、git が動く環境なら他の OS でも大丈夫だと思います[^install]）。

[^install]: git-foresta は Perl で書かれており、必要な依存モジュール等は [App::Fatpacker::Simple](https://github.com/skaji/App-FatPacker-Simple) を使って含めています。git は一部のコマンドが Perl 依存なので、 git のインストール時に Perl も一緒に自動で入ります。ですので、 git が動く環境なら git-foresta も動くはずです。

例えばすでに ~/bin に PATH が通っているならば、 下記ようにワンライナーでインストールできます:

```bash
curl -L https://github.com/takaaki-kasai/git-foresta/raw/master/git-foresta -o ~/bin/git-foresta && chmod +x ~/bin/git-foresta
```

# Tips
* `--no-status` オプションを付けなければ、 `HEAD` の隣にワーキングツリーの状態を表示します。表示される記号の意味は次の通りです（git の公式配布ファイルに含まれている `git-prompt.sh` と意味を揃えてます）。
  - `*`: add されてない変更がある（unstaged）。
  - `+`: add されているが commit されていない変更がある（staged）。
  - `%`: add されてない新規ファイルがある（untracked）。
  - `$`: stash になにか入っている（stashed）。

* 下記は zsh での短縮呼び出し設定例です。 `gifo`・`gifa` でそれぞれ通常版と `--all` 付き版を呼び出せて `git log` と同等の補完が効きます。引数も普通に渡せます。

  ```zsh:~/.zshrc
  function gifo() { git-foresta --style=10 "$@" | less -RSX }
  function gifa() { git-foresta --all --style=10 "$@" | less -RSX }
  compdef _git gifo=git-log
  compdef _git gifa=git-log
  ```

* ページャとして less を使うなら、横スクロールのキーバインドを Vim 風にしておくと便利でしょう。
  → 参照： [PAGERを less \-S にしたときの横スクロールをlesshstでvim風にする \- だるろぐ](http://d.hatena.ne.jp/hirafoo/20110402/1301708251)

* フォントによっては、「罫線素片（コミットグラフの線）」と「グラフのシンボル」の表示幅が異なるために、グラフがずれて表示されることがあります。その場合は、 `--graph-symbol-commit` などのオプションを使い、グラフのシンボルに「罫線素片と同じ幅で表示される文字」を指定することでグラフのずれを解消できます。

---

2017-05-08: .zshrc 設定例で引数を受け取る箇所を `$@` -> `"$@"` に修正しました （thanks to @fumiyas ）
2017-05-09: `less -RS` を `less -RSX` に変更しました （thanks to 後輩のH君）
2017-05-11: インストール方法にワンライナーの例を追加 (thanks to http://b.hatena.ne.jp/entry/336358994/comment/y-kawaz)
2017-05-15: 使い方に `--version` オプションの記述を追加
2017-05-18: Tipsにフォントが理由でグラフがずれることへの対処方法について記述を追加
2017-05-19: インストール方法に動作確認済みのOSについて記述を追加