ローカルリポジトリの管理方法

> Fishermanは名前を変更しFisherとなったため、それにともない内容を修正しました。

みなさんローカルリポジトリの管理ってどうしてますか？

僕は少し前まではホームディレクトリに`Repositories`なんてディレクトリを作ってそこにgitでcloneしていました。

最近fish + Ghq + fzfで管理し始めたんですけど、戻れなくなったので紹介してみたいと思います。

実はこの記事と似たような内容の記事を少し前に書いています。

[fish shellが結構良かった話 - Qiita](https://qiita.com/hennin/items/33758226a0de8c963ddf)

こっちは完全にfish寄りの内容なんですけど、興味のある方は読んでみてください。

それでは先にfishとGhqとfzfそれぞれの大雑把な紹介だけしていきます。

その後で細かい環境構築を紹介していく感じでいきたいと思います。


# fish shell

[fish shell](https://fishshell.com/)

fishは他のシェルに比べて**補完がとても強力**です。

**デフォルトでいい感じ**なので特に**難しい設定なども必要ありません**。

また、**入力中のコマンドにもシンタックスハイライトが効く**ので、コマンドのタイプミスを心配せずに書けてしまいます。

![Screenshot at 2018-05-25 10-59-34.png](https://qiita-image-store.s3.amazonaws.com/0/225715/4cda2d62-c970-f97c-90c7-5c96f03f34b8.png)

**存在しないコマンド**だと**赤色のハイライト**で知らせてくれます。

もちろんコマンドの**オプションの補完**もできます。

![Screenshot at 2018-05-25 11-09-31.png](https://qiita-image-store.s3.amazonaws.com/0/225715/5e56cb99-476e-32a2-179d-304a8c78e56e.png)

また、Returnを押したときそこでコマンドが終わりなのか、まだ入力の途中で**改行が必要なのか**を**自動で判別してインデント**までしてくれます。

![Screenshot at 2018-05-25 11-16-35.png](https://qiita-image-store.s3.amazonaws.com/0/225715/4ca711ee-2fbd-a449-6967-a1e5a950fdaa.png)

ただ**POSIX互換ではない**という弱点もあるので、そこは少し気を付ける必要がありますね。


# Ghq

[GitHub - motemen/ghq: Remote repository management made easy](https://github.com/motemen/ghq)

今回の目玉となるツールで、簡単に言うと**git cloneを一箇所で管理するためのツール**です。

ちなみにGo製です。

基本は`ghq get`でリポジトリをcloneしてきて、`ghq look`でそのリポジトリに移動する感じです。

![Screenshot at 2018-05-25 14-42-38.png](https://qiita-image-store.s3.amazonaws.com/0/225715/cc45e256-8f57-1a96-190a-7941180c4b04.png)

fishで実行しているのでカラフルで補完もいい感じですね。


# fzf

[GitHub - junegunn/fzf: A command-line fuzzy finder](https://github.com/junegunn/fzf)

fzfはfuzzy finderといって、**あいまい検索の機能を提供するツール**です。

こちらもGo製です。

GoってCLIツールとか作るのに向いてるんでしょうか。

使い方は簡単で、**入力に行データを取り**、**あいまい検索**を行って**検索結果のデータを出力**します。

行データというのは、たとえば`ls -l`の結果とかのことです。

- 行データを渡す

![Screenshot at 2018-05-25 11-55-01.png](https://qiita-image-store.s3.amazonaws.com/0/225715/7bd46c5e-ee75-6fd2-3399-81f244018982.png)

- 検索中

![Screenshot at 2018-05-25 11-51-15.png](https://qiita-image-store.s3.amazonaws.com/0/225715/bab09702-6d7e-6673-47e5-c79b9c28d38c.png)

あいまい検索なので、適当な入力でもヒットします。

- 出力

![Screenshot at 2018-05-25 11-56-29.png](https://qiita-image-store.s3.amazonaws.com/0/225715/e925b08c-9ef3-11b5-4d31-5c66d6e50715.png)

~~余談ですけどコマンドの**実行時間が赤色で表示**されててfish賢い！という感じですね。~~

実行時間が1分を超えると赤くなるだけみたいですね。


# 環境構築

fishとGhqとfzfはそれぞれ強力なツールでしたけど、組み合わせることでさらに便利なものになります。

簡単に言うと、**強力な補完の力を借りながらローカルリポジトリをあいまい検索で移動できる**感じです。

## fishのインストールと設定

まずはお使いのパッケージマネージャでfishをインストールします。

```sh:ArchLinuxの例
$ yaourt -S fish
```

次に、fishのプラグイン管理ツールであるFisherをインストールします。

Fisher、Fishermanから名前変わったみたいですね。

[GitHub - jorgebucaran/fisher: A package manager for the fish shell](https://github.com/jorgebucaran/fisher)

上記のGithubのページにインストール用のワンライナーがありますので、fishシェルを起動してから実行してみてください。

```sh
$ fish

$ curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
```

「パッケージマネージャを使わずにソフトウェアを入れるのは嫌だ」と思う人もいるかもしれませんけど、そこは大丈夫です。

fishは標準で`~/.config/fish/functions`以下のファイルにあるfishの関数を読み込んで実行できるんですけど、Fisherはその機能を使って作られています。

なのでパッケージマネージャ外からソフトウェアを入れたせいで管理ができなくなるみたいなことはありません。

閑話休題。

Fisherの使い方は詳しくは説明しませんけど、`fisher`のあとに続くサブコマンドが`add`、`rm`、`ls`とかです。

fishをデフォルトシェルにしたい人は以下を実行してください。

```sh:shの例
$ chsh -s $(which fish)
```

```sh:fishの例
$ chsh -s (which fish)
```

**POSIX準拠じゃないシェルをログインシェルにするのは怖い**という人は、お使いのシェルの設定ファイルの最後に以下を記述してください。

```sh:.bashrcの例
exec fish
```

fishの設定はこれぐらいです。

見た目をいじりたい人は`fish_config`を実行して表示されたURLを見に行くと幸せになれます。

![Screenshot at 2018-05-25 12-15-50.png](https://qiita-image-store.s3.amazonaws.com/0/225715/031661c2-09d7-44af-20cd-95bcca0be94a.png)


## fzfのインストールと設定

まずはお使いのパッケージマネージャでfzfをインストールします。

```sh:ArchLinuxの例
$ yaourt -S fzf
```

そしてFisherでfishのfzf用のプラグインを入れます。

[GitHub - jethrokuan/fzf: Ef-🐟-ient fish keybindings for fzf](https://github.com/jethrokuan/fzf)

```sh:fish
$ fisher add jethrokuan/fzf
```

このfzfのプラグインですけど、少しだけ設定が必要になります。

このプラグインのデフォルトのキーバインドがfish 2.4.0のキーバインドと衝突してしまったからだそうです。

なので、fishの設定ファイルである`~/.config/fish/config.fish`に以下を書き込みます。
なかったら新しく作ってください。

```sh:config.fish
set -U FZF_LEGACY_KEYBINDINGS 0
```

これでNew Keybindingsの方のキーバインドが使えますね。

![Screenshot at 2018-05-25 12-29-11.png](https://qiita-image-store.s3.amazonaws.com/0/225715/a20c632b-4f4d-193c-f7af-8c73191bbb02.png)

コマンド履歴をあいまい検索するキーバインド`Ctrl + r`とかがデフォルトで用意されていますね。

![Screenshot at 2018-05-25 12-35-55.png](https://qiita-image-store.s3.amazonaws.com/0/225715/24fb38b6-b900-88af-8fba-58b529b13bd7.png)

とても便利ですね。


## ghqのインストールと設定

fzfのときと同じような流れです。

```sh:ArchLinuxの例
$ yaourt -S ghq
```

[GitHub - decors/fish-ghq: ghq completion and keybinding for fish shell](https://github.com/decors/fish-ghq)

```sh:fish
$ fisher add decors/fish-ghq
```

`ghq get`はデフォルトで`~/.ghq`にリポジトリをcloneしてきます。

`ghq root`で確認できます。

cloneするディレクトリを変更したいときは`~/.gitconfig`に以下の設定を書き込みます。

```sh:.gitconfig
[ghq]
        root = ~/Repositories
        root = ~/.go/src
```

ディレクトリはいくつか設定できて、`ghq get`では一番上のところにcloneされます。

ちなみにですけど、`ghq get`は`git clone`のエイリアスなので手動でcloneしてきても大丈夫です。

デフォルトで用意されているキーバインドは`Ctrl + g`だけで、これは`ghq root`にあるローカルリポジトリをfzfを使ってあいまい検索します。

fzfを入れておくだけで勝手に利用してくれるみたいです。

便利ですね。

使い勝手が知りたい人は、`ghq get`でいっぱいリポジトリもってきて`Ctrl + g`であいまい検索してみてください。

- `ghq get`
![Screenshot at 2018-05-25 14-45-45.png](https://qiita-image-store.s3.amazonaws.com/0/225715/aaab12d4-7cbc-f261-2795-a5b0d1a4b048.png)


cloneしてきたリポジトリのパスは`/path/to/ghq-root/github.com/username/repository.git`となるみたいですね。

で、`Ctrl + g`であいまい検索します。

- `Ctrl + g`

![Screenshot at 2018-05-25 14-48-12.png](https://qiita-image-store.s3.amazonaws.com/0/225715/2ffe5441-49ef-ea1a-9e47-24af48ddc214.png)

Returnするとそのリポジトリのディレクトリに飛べます。

- 移動
![Screenshot at 2018-05-25 14-50-43.png](https://qiita-image-store.s3.amazonaws.com/0/225715/128d82dc-c1bc-3020-ff69-3bfa207bf57b.png)

まずGhqを利用することでローカルリポジトリの位置が

`/path/to/ghq-root/github.com/username/repository`

と決められて、一括で管理できるのでいいですね。

`github.com`のところは`gitlab.com`だったり`bitbucket.org`だったりします。

そしてfzfを利用していることでリポジトリへの移動を曖昧検索で素早く行うことができますね。

そして何よりfishを使っていることで、補完がとにかく強力なので作業効率が上がること間違いなしです。

# まとめ

fish+Ghq+fzfすることでローカルリポジトリの移動、検索がとても簡単になりました。

fishの補完がすごいのでコマンドのミスタイプを目grepするようなストレスからも開放されましたね。

fishはこれ以外にも色々楽しいことがあるので、興味があれば以下の記事も読んでみてください。

[fish shellが結構良かった話 - Qiita](https://qiita.com/hennin/items/33758226a0de8c963ddf)

あとfzfは紹介した用途以外でも結構使い勝手の良いコマンドです。

`ls`したときとか、パッケージマネージャでパッケージを検索したときとか、出力が途方もない量になることってありますよね。

そういうときはパイプでlessやgrepに流すことが多いと思いますけど、そこにfzfも加えてみると少しだけ幸せになれるかもしれません。

脱線が主になってしまっていた感は否めませんでしたけど、一応ローカルリポジトリの管理方法の紹介でした。

# 参考文献

[Public Domain Lisp Logo Set By <a href="mailto:lisperati@gmail.com">Conrad Barski, M.D.</a> ](http://lisperati.com/logo.html)
[GitHub - jorgebucaran/fisher: A package manager for the fish shell](https://github.com/jorgebucaran/fisher)
[GitHub - junegunn/fzf: A command-line fuzzy finder](https://github.com/junegunn/fzf)
[GitHub - motemen/ghq: Remote repository management made easy](https://github.com/motemen/ghq)
[GitHub - jethrokuan/fzf: Ef-🐟-ient fish keybindings for fzf](https://github.com/jethrokuan/fzf)
[GitHub - decors/fish-ghq: ghq completion and keybinding for fish shell](https://github.com/decors/fish-ghq)