macOSのgitアップデートとプロンプト表示について

2022-12-25

macの移行に伴い、最新のgitインストールから補完設定までを行ったメモ。

環境

  • zsh 5.9 (arm-apple-darwin21.3.0)
  • macOS Monterey 12.6

homebrewで最新のGitを利用する

Macにプリインストールされているgitはバージョンが古いので、homebrewでインストールしたgitに移行する。 プリインストールされたgitのインストール先を確認。

$ which git
/usr/bin/git
$ git --version
git version 2.37.1 (Apple Git-137.1)

brewでgitをインストールする。

$ brew install git
==> git: stable 2.39.0 (bottled), HEAD
Distributed revision control system
https://git-scm.com
/opt/homebrew/Cellar/git/2.38.1 (1,592 files, 48.1MB) *
  Poured from bottle on 2022-11-18 at 14:29:15
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/git.rb
License: GPL-2.0-only
==> Dependencies
Required: gettext ✔, pcre2 ✔
==> Options
--HEAD
        Install HEAD version
==> Caveats
The Tcl/Tk GUIs (e.g. gitk, git-gui) are now in the `git-gui` formula.
Subversion interoperability (git-svn) is now in the `git-svn` formula.

Bash completion has been installed to:
  /opt/homebrew/etc/bash_completion.d
==> Analytics
install: 340,526 (30 days), 1,086,049 (90 days), 3,535,289 (365 days)
install-on-request: 334,624 (30 days), 1,067,520 (90 days), 3,465,417 (365 days)
build-error: 16 (30 days)

最新のgitが更新されていることを確認する。

% git --version
git version 2.38.1
% which git
/opt/homebrew/bin/git

homebrewでインストールしたgitが反映されない

brewのパッケージインストール先がシェルのパスに含まれていなかった。

brewのパッケージをインストールするディレクトリは prefix オプションで確認できる。 説明にあるようにmacOSでもintelとamd(M1)でインストール先が異なる。

% man brew
...省略
   --prefix [--unbrewed] [--installed] [formula ...]
       Display Homebrew´s install path. Default:

       •   macOS Intel: /usr/local

       •   macOS ARM: /opt/homebrew

       •   Linux: /home/linuxbrew/.linuxbrew
...省略

シェルのPATHを追加する。環境に依存しないよう brew コマンドの実行結果を指定する。

~/.zshrc

export PATH="$(brew --prefix)/bin:$PATH"

gitの補完・プロンプト表示を有効にする

GitHubのリポジトリにあるスクリプトを利用してgitの補完やプロンプトでのブランチ表示を有効にする。

各ファイルのコメントに導入方法が記述されているが、zshの場合はそれぞれの関係を把握するためにある程度スクリプトの内容を理解する必要があったので残しておく。

zshでの導入方法

補完を有効にするだけなら git-completion.bashgit-completion.zsh 2つのファイルを利用する。 git-prompt.sh はプロンプトへのブランチ表示など独立した機能を提供する。

zshで利用するためには git-completion.bashgit-completion.zsh 2つのファイルを同じディレクトリに配置する。git-completion.zsh はファイル名を変更しても良いが、 git-completion.bashgit-completion.zsh 内で参照されるためファイル名が一致している必要がある。

自分の環境では ~/.zsh/functions にダウンロードした。

git-completion.bash

サブコマンドやブランチ名などを補完するためのシェルスクリプト。

~/.zsh/functions/git-completion.bash にファイルをダウンロードする。(bashの場合はこのスクリプトを読み込むが、zshではラッパーを介して利用するためダウンロードのみで良い)

% wget -O ~/.zsh/functions/git-completion.bash https://raw.githubusercontent.com/git/git/a68dfadae5e95c7f255cf38c9efdcbc2e36d1931/contrib/completion/git-completion.bash

git-completion.zsh

zshでgitの補完を有効にする処理が書かれた git-completion.bash のラッパースクリプト。zshの補完システムで利用されるモジュール。

~/.zsh/functions/_git にファイルのダウンロードする。

% wget -O ~/.zsh/functions/_git https://raw.githubusercontent.com/git/git/a68dfadae5e95c7f255cf38c9efdcbc2e36d1931/contrib/completion/git-completion.zsh

~/.zshrc$fpath にダウンロードしたスクリプトを追加する。

fpath=(${HOME}/.zsh/functions ${fpath})

確認

.zshrcを読み込むかzshを起動しコマンドやブランチが補完されるか確認する。

. ~/.zshrc
# または
zsh

サブコマンドを途中まで入力する。続けてtabを入力し補完を確認。

% git pu
pull  -- fetch from and merge with another repository or a local branch
push  -- update remote refs along with associated objects

ブランチを途中まで入力する。続けてtabを入力し補完を確認。

% git pull o
# tabを押す
% git pull origin

git-prompt.sh

環境変数 PS1__git_ps1 を呼び出すことで、プロンプトにgitリポジトリのステータスを表示可能になる。

スクリプトをダウンロードする。

% wget -O ~/.git-prompt.sh https://raw.githubusercontent.com/git/git/a68dfadae5e95c7f255cf38c9efdcbc2e36d1931/contrib/completion/git-prompt.sh

~/.zshrc に読み込み設定する。

source ~/.git-prompt.sh

トラブルシュート

~/.zshrc読み込み時に this script is obsolete, please see git-completion.zsh が出力される

zshで git-completion.bash を読み込んでいる場合に警告される。

なぜ変数の参照に - が含まれるか

bash は $BASH_VERSION、zsh は $ZSH_VERSION というシェル変数にバージョン文字列が入るため、これで種類の判定ができます。 ちなみに $VAR でなく ${VAR-} としているのは、 set -u (未定義パラメーターの展開をエラーとする) されている場合にも対応するためです。 bash はメジャー、マイナー、マイクロバージョン番号が $BASH_VERINFO に配列で設定されています。zsh は $ZSH_VERSION から切り分ける必要があります。 また、動作モードは bash は $BASH の値、zsh は emulate 組込みコマンドの出力で判定できます。

git-completion.zsh での bash-completion.bash について

git-completion.zsh における bash-completion.bash を走査する優先順位

    1. :completion:*:*:git:* のコンテキスにおける script の値
    1. git-completion.zsh が置かれているディレクトの git-completion.bash
    1. $HOME/.local/share/bash-completion/completions/git
    1. $bash_completion/git
    1. /etc/bash_completion.d/git

今回は 2. で読み込まれる様にスクリプトを配置した。2.から6.に一致しないパスに git-completion.bash を配置した場合は、script スタイルにパスを設定すればいい。

git-completion.bash~/.git-completion.bash にダウンロードした場合は下の記述を .zshrc に追加する。

zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
fpath=(${HOME}/.zsh/functions ${fpath})

zshの補完システムは $FPATH に指定されたディレクトリに含まれるアンダースコア( _ )で始まる関数を自動的に読み込む。

参考


Web系ソフトウェアエンジニアの備忘録

Contact: 3982ne@gmail.com