[Ubuntu] コマンドライン上にgitブランチ名を表示する

# 始めに
　単純にブランチ名を表示する方法なら色々情報があったのですが、環境差異で微妙に手順が違ったので、備忘も兼ねて記事にまとめておこうと思います。

　手順のみ知りたい方は要約を、それ以降はお好みで[^3]。


# やりたい事
↓ な感じで、コマンドライン上にブランチ名を表示させる事が、今回のゴールです！💪💪
```bash
user@:/home/username/my-repository # 
↓
user@:/home/username/my-repository (main) # 
```


# 環境
　OS： Ubuntu 20.04 / 22.04
　git： 2.25.1


# 要約
```bash
user@:/home/username/my-repository (main) # 
```
のように、コマンドライン上にブランチ名を表示させるためには、
```bash:.bashrc
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1) \$ '
# or
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(__git_ps1)\$ '
```
のように`$(__git_ps1)`を指定すればOK👌

`__git_ps1: command not found.` が発生した場合は、git-completion.bash と git-prompt.sh を事前に読み込ませる。
```bash:.bashrc
source ~/.git-prompt.sh
source ~/.git-completion.bash

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(__git_ps1)\$ '
```

上記2ファイルが存在なければ、[gitのソース](https://github.com/git/git/tree/master/contrib/completion)から取得。
凡そ、下記のどこかに存在するみたいです（自分の環境では最後者）。
```bash
/usr/local/etc/bash_completion.d/
/usr/share/bash-completion/
```


# .bashrc を確認
　`~/.bashrc`というファイルを編集すればよいらしいので、まずは確認してみます。👀
編集前は下記の状態でした。
```bash:.bashrc（編集前）
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# (中略)

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# (以下略)
```

`PS1` という変数が、コマンドラインの表示内容を決めているらしいです。
自分の場合は、デフォルトだとカラー表示されていなかったので、 else の方が適用されているようでした。

${...} は一旦無視するとして、`\u@\h:\w\$ ` という部分に注目[^07]すると、

```bash
\u : ユーザー名
\h : ホスト名
\W : 今いるディレクトリ名
\$ : 一般ユーザーの時$, rootの時#を表示
```
なので[^10]、`user`というユーザでログインしていて、`/home/username`というディレクトリにいる場合、
```
user@:/home/username$ 
```
と表示される事になります。


# .bashrc を編集
　構文を理解したところで、さっそく編集に入ります。
修正箇所は2つありますが、カラー変更できる設定なら前者のみでも大丈夫です。
```diff:.bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# (中略)

if [ "$color_prompt" = yes ]; then
-   PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
+   PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1) \$ '
else
-   PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
+   PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(__git_ps1) \$ '
fi
unset color_prompt force_color_prompt

# (以下略)
```

保存したら、
```bash
source ~/.bashrc
```
で設定を反映させれば完了です！🎉🎉


# __git_ps1: command not found. が出たら
```bash
source ~/.bashrc
```
と打った際に、`__git_ps1: command not found.`が出た時の対処法です。
自分もこれが出ました😇

## git-completion.bash と git-prompt.sh を用意
参考2によれば、git-completion.bash と git-prompt.sh のファイルがあれば良いらしいですが、
```bash
$ ls /usr/local/etc/bash_completion.d/
brew            git-completion.bash git-prompt.sh
```

自分の環境では`/usr/local/etc/` が空でした。
```bash
$ ls /usr/local/etc/
$ # 空っぽ
```

方々探したところ、`/usr/share`配下に`bash-completion/`があり、
```bash
$ ls /usr/share/bash-completion
bash_completion  completions/  helpers/
```

また`bash-completion/completions/git`には、
```bash
# bash/zsh completion support for core Git.
#
# (中略)
#
# To use these routines:
#
#    1) Copy this file to somewhere (e.g. ~/.git-completion.bash).
#    2) Add the following line to your .bashrc/.zshrc:
#        source ~/.git-completion.bash
#    3) Consider changing your PS1 to also show the current branch,
#       see git-prompt.sh for details.
# (以下略)
```
とあるので、参考2の配置場所に合わせて、.git-completion.bash を`bash-completion/`配下に作っておきます。
```bash
$ cp bash-completion/completions/git ~/.git-completion.bash
```

.git-prompt.sh は見つけられなかったので、git のソースから取得して(参考3)、同じくユーザ直下`~/.git-prompt.sh`に配置しました。

最終的な状態は下記の通りです[^15]。
```bash
$ ls ~ -a
.  ..  .git-completion.bash  .git-prompt.sh  bash_completion  completions/  helpers/
```

## .bashrc を再度編集
　`$(__git_ps1)\$`を使用する直前で[^20]、git-completion.bash と git-prompt.sh を読み込ませます[^23]。



```diff:.bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# (中略)

# ↓2行を加える
+ source ~/.git-prompt.sh
+ source ~/.git-completion.bash

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$(__git_ps1) \$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(__git_ps1)\$ '
fi
unset color_prompt force_color_prompt

# (以下略)
```

再度設定を反映すれば、今度こそ完了です！🎉🎉🎉
```bash
source ~/.bashrc
```

# 終わりに
不備や誤字等ありましたら、編集リクエストお願いいたします🙇‍♂️

# 参考
1. [Bashプロンプトの変更](https://qiita.com/zaburo/items/9194cd9eb841dea897a0)
2. [gitのブランチ名をターミナルで表示できるようにする](https://qiita.com/lemtosh469/items/334ff76366e054a3a3aa)
2. [A1.4 付録 A: その他の環境でのGit - BashでGitを使う](https://git-scm.com/book/ja/v2/%E4%BB%98%E9%8C%B2-A%3A-%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E7%92%B0%E5%A2%83%E3%81%A7%E3%81%AEGit-Bash%E3%81%A7Git%E3%82%92%E4%BD%BF%E3%81%86)

[^3]: 調査内容をおおよそ時系列で記録してるだけなので
[^07]: 末尾に半角スペースあり
[^10]: 参考1より改変して転記させて頂いています
[^15]: gitのソースから取得した[git-prompt.sh](https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh)には、`.git-prompt.sh`と隠しファイルで作成するように記載されていたので、今回はその対応にしました。`git-prompt.sh`でも問題なさそうですが、本当はどっちがいいんでしょう。。。🤔
[^20]: 個人的に、出来るだけ使用する直前で、読み込ませたかったので。
[^23]: `GIT_PS1_SHOWDIRTYSTATE=1` も追加しておくと、未コミットのファイルがある時に表示が出るらしい(参考3)ですが、今回は省略しました。