修正する

修正する

私のzshシェルはgitリポジトリ内にあるかどうかに応じてプロンプトを動的に変更します。確認するには、次のgitコマンドを使用しています。

if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
...

現在のディレクトリが無視されるかどうかを区別したいと思いますgit。だから私は宣言ifにもう一つの確認を追加しました。

if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1) && ! $(git check-ignore . >/dev/null 2>&1); then
...

これはうまくいきますが、単一のコマンドで単純化できるかどうか疑問に思いますgit。プロンプトは毎回更新されるため、ENTER一部の低速システムではシェル速度が大幅に遅くなる傾向があります。

修正する

@Stephen Kittが受け入れた解決策は、以下を除いてうまくいきます。

ファイルシステム全体でリポジトリを使用しています。 gitが別のパーティション/ファイルシステムにありますが/.git(設定ファイルを追跡したいので/etc)、gitにあるいくつかのファイルも追跡したいとします。/var/foo

次のコマンドを実行すると、/すべてが期待どおりに機能し、戻りコードを取得します1/var/foo追跡中です)。

# git check-ignore -q /var/foo

ただし、存在する場合、/var同じコマンドはエラーコード128と次のエラーメッセージで失敗します。

# git check-ignore -q /var/foo
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

しかし、私の考えでは、それはcheck-ignore順序の問題だけです。それ以外の場合は、gitがファイルシステムで正常に動作しているようです。/var/fooファイルをうまく追跡できます。

予想される動作は、追跡されない場合にgit check-ignore -q /var/foo返されるものです。1git check-ignore -q /var/bar0

この問題をどのように解決できますか?

答え1

git check-ignore ..リポジトリにない場合は、終了コード128で失敗し(または他のエラーが発生した場合)、パスが無視されないgit場合にのみ終了コード1で失敗します。したがって、後者のみを確認できます。

git check-ignore -q . 2>/dev/null; if [ "$?" -ne "1" ]; then ... 

then内部的には、gitリポジトリで無視または無視されない状況を処理しています。.

ファイルシステムの境界を超えて機能させるには、次のように設定します。GIT_DISCOVERY_ACROSS_FILESYSTEM到着true:

GIT_DISCOVERY_ACROSS_FILESYSTEM=true git check-ignore -q . 2>/dev/null; if [ "$?" -ne "1" ]; then ...

答え2

最初にすべきことは:

if
  git rev-parse --is-inside-work-tree >/dev/null 2>&1 &&
    ! git check-ignore . >/dev/null 2>&1
then...

コマンド置換($(...))はコマンドの出力を検索します。ここでにリダイレクトするときに出力はありません/dev/null。出力がある場合は、実行されるコマンドとして処理されます(終了ステータスの確認)。

2 番目のコマンドは、最初のコマンドが成功した場合にのみ実行されます。

git@StephenKittは、これら2つのコマンドを1つのコマンドに分割する方法を示しました。しかし、それでもパフォーマンスに役立たない場合は、いつでも関連配列に情報をキャッシュできます。

typeset -A is_git # declared globally in your ~/.zshrc
if (( ! $+is_git[$PWD] )); then
  git check-ignore -q . 2> /dev/null
  is_git[$PWD]=$(( $? == 1 ))
fi

if (( $is_git[$PWD] )); then...

ディレクトリの名前を変更したり、ディレクトリを削除したり、無視されたファイルのリストを変更したりすると、.gitこのキャッシュが古くなる可能性があります。これを使用または再起動してis_git=()無効にすることができます。zshexec zsh

別のオプションは、フックを使用してディレクトリが入力されたときにのみ確認することですchpwd

check_git() {
  git check-ignore -q . 2> /dev/null
  (( is_git = $? == 1 ))
}
chpwd_functions+=(check_git)

次に、プロンプトルーチンで次の操作を行います。

if (( is_git )); then...

関連情報