1
Help us understand the problem. What are the problem?

posted at

updated at

Organization

Git switch の補完ができなかった

課題

git checkout から git switch に変更しようと思って,

alias gco='git switch' としていたのだが,補完が効かないので調べてみた.

まとめ

  • 掃除をした
$ rm ~/.zfunctions/Completion/_git
$ tmux set-environment -gu FPATH

環境

  • zsh : 5.8 (brew)
  • Mac
$ where zsh
/usr/local/bin/zsh
/bin/zsh
$ zsh --version
zsh 5.8 (x86_64-apple-darwin19.6.0)
$ /bin/zsh --version
zsh 5.7.1 (x86_64-apple-darwin19.0)
$ which _git | head -1
_git () {
$ which _git-switch
_git-switch not found
zsh: exit 1

そもそも switch サブコマンドの定義が存在していない…

古い定義が残っていた

$ printf "%s\n" $fpath
/Users/username/.zfunctions/Completion
/usr/local/share/zsh/site-functions
/usr/share/zsh/site-functions
/usr/share/zsh/5.7.1/functions

~/.zfunctions/Completions にある _git ファイルが古かったので削除する.

$ grep switch ~/.zfunctions/Completion/_git
[1]    33448 exit 1
$ rm !$

キャッシュをクリアする.

$ rm -f ~/.zcompdump; compinit

今のパス見てない?

そもそも,site-functions はあるけど functions がパスされてない…

$ grep git-switch /usr/local/share/zsh/functions/_git
(( $+functions[_git-switch] )) ||
_git-switch() {
~/.zshrc
+if [[ -d /usr/local/share/zsh/functions ]]; then
+  fpath=(${fpath} /usr/local/share/zsh/functions)
+fi
$ source ~/.zshrc
$ printf "%s\n" $fpath
/Users/username/.zfunctions/Completion
/usr/local/share/zsh/site-functions
/usr/share/zsh/site-functions
/usr/share/zsh/5.7.1/functions
/usr/local/share/zsh/functions

よし.これで大丈夫だと思ったらまだ駄目だった.

$ rm -f ~/.zcompdump; compinit

他にもある

/usr/share/zsh/5.7.1/functions/_git ファイルが存在していて,そのファイルも古そうだった.

$ for f in $fpath; do ls $f/_git; done
/usr/share/zsh/5.7.1/functions/_git
/usr/local/share/zsh/functions/_git@
$ grep switch /usr/share/zsh/5.7.1/functions/_git
    '(-f --force -m --merge --conflict --patch)'{-f,--force}'[force branch switch/ignore unmerged entries]' \
        w:'switch line wrapping'

パスの順番間違えてました.

~/.zshrc
+if [[ -d /usr/local/share/zsh/functions ]]; then
+  fpath=(/usr/local/share/zsh/functions ${fpath})
+fi

今使っている zsh は 5.8 なのに ,/usr/share/zsh/5.7.1/functions はどこから来たんだ…

ログインシェルが…

ログインシェルが,/bin/zsh になっていた.
こちらならば,/usr/share/zsh/5.7.1のパスを見ていてもおかしくはない.

じゃあ,なんで $SHELL=/usr/local/bin/zsh だったのかというと,
普段使っているtmux の default-shell が /usr/local/bin/zsh だからか.
/bin/zsh がターミナル起動時に起動して,tmux から /usr/local/bin/zsh を起動している状態になっている.
動作を確認してみる.

# 一度 .zshrc を退避する
$ mv ~/.zshrc ~/.zshrc.bak

# ターミナルを新しく開く(tmux 無い状態)
% echo $SHELL
/bin/zsh
% edit ~/.zshrc
% cat ~/.zshrc
printf "%s\n" $fpath
% source ~/.zshrc
/usr/local/share/zsh/site-functions
/usr/share/zsh/site-functions
/usr/share/zsh/5.7.1/functions

# この状態で /usr/local/bin/zsh を実行してみる
% /usr/local/bin/zsh
/usr/local/share/zsh/site-functions
/usr/local/Cellar/zsh/5.8_1/share/zsh/functions

/bin/zsh/usr/local/bin/zsh では,特に問題はない.tmux で使ってると予期しないパスになる?

##### $ ps -efE | awk '{if($2==tmuxのPID){print}}' # こうやらなくとも良かっ
$ tmux show-environment -g | grep -i fpath

これで見ると,tmux$FPATH/bin/zsh のものを使っているようだ.
それを引き継いでいるので予期しない状態になっていた.

この環境変数要る?

と思ったけど,そもそも 環境変数 $FPATH が要らないのではないか.

$ echo $SHELL
/bin/zsh
$ env|grep -i fpath
$

/bin/zsh を起動しただけであれば,$FPATH は設定されていない.
だから,この後起動したサブシェルに引き継がれていないのだ.
今の起動している tmux には環境変数 $FPATH が設定されている.

$ tmux set-environment -gu FPATH

すれば,環境変数を削除できそうではある.

どうするか

できれば原因を排除しておきたい.
軽く試したところ起動時に環境変数が設定されていれば tmux に環境変数が受け継がれるがそのような設定はしてなそうだった.
tmux を起動する前だから,.zshrc 辺りが怪しいが,今となってはわからない.
何か気付いたら追記しよう.

追記

tmux 内部のシェルで環境変数にすると tmux サーバーに保存されるような気がする.
一度環境変数にししてしまったのかもしれない.

追記2

どうやら,FPATH 環境変数は設定されるもののようだ.

tmux.conf
if-shell "env | grep FPATH" "set-environment -gu FPATH"

を追加して様子を見ることにする

まとめ

  • 過去設定した古いファイルがが残っていたので掃除した
  • 初期化を疑ったが,その状況は残っていなかった
  • tmux に環境変数が残っていると,そのサブシェルに引き継がれる

Referernces

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?