zsh エイリアスがあります。
gitbs() {
git branch | grep -- $1
}
次のように結果をgit checkoutに渡したいと思います。
git checkout | gitbs state
どうすればこれを行うことができますか?
ベストアンサー1
シェルパイプは、あるコマンドの出力を別のコマンドの入力に渡します。ここでは役に立ちません。コマンドの出力をコマンドライン引数として別のコマンドに渡そうとします。これを行うツールは次のとおりです。コマンドの置き換え。だから基本的なアイデアは
git checkout "$(gitbs state)"
(これはパイプですが、パイプの読み取り端はシェル自体です。出力を読み取ってから、その出力を含むコマンドラインを設定します。)
ただし、出力はgitbs state
渡すのに正しい形式ではありませんgit checkout
。ブランチ名と同じ行に追加のスペースがあり、時には句読点があります。 (色の書式設定コードもありますが、出力が端末に渡された場合、またはgitが自動的にポケットベルを呼び出す場合にのみ適用され、出力がパイプである場合はありません)。情報のエラーgit checkout
。
gitbs
この問題を解決するには、元のブランチ名を出力として生成するように変更できます。以下は、出力が端末の場合は人のためのきれいな形式を維持し、それ以外の場合は1行に分岐名を印刷するバージョンです。それを使うgit for-each-ref
支店名を列挙します。これ条件式 -t 1
標準出力が端末かどうかをテストします。
gitbs () {
if [[ -t 1 ]]; then
git branch
else
git for-each-ref --format='%(refname:lstrip=2)' 'refs/heads/*'
fi | grep -- "$1"
}
この定義でgitbs
それはgit checkout "$(gitbs state)"
すべてです。
コマンド置換の周りに二重引用符があります。二重引用符()がない場合、出力はスペースから別の引数に分割されるため、複数のブランチが一致すると、結果コマンドはチェックアウトするのではなく、ファイルの現在のバージョンをgit checkout $(gitbs state)
git checkout foobar1 foobar2
ifのバージョンで上書きします。名前のファイルが存在します。foobar1
foobar2
foobar1
foobar2
gitbs
これらのトラップを回避するには、一致する単一のブランチが必要な別のバージョンを定義することをお勧めします。一致するブランチがゼロを超える場合、現在のブランチに関する追加メッセージは引き続き表示されますが、より明確なエラーメッセージが表示されますgit checkout
。この関数は一致する分岐のリストを大量に
gitbs1 () {
local branches
branches=($(git for-each-ref --format='%(refname:lstrip=2)' 'refs/heads/*' | grep "$1"))
if ((#branches == 0)); then
echo "No branch contains '$1'" >&2
return 3
fi
if ((#branches > 1)); then
echo "Multiple branches match '$1':" >&2
print -lr $branches >&2
return 3
fi
echo $branches
}
これで自信を持って書くことができますgit checkout $(gitbs1 state)
。
このオプションをオンにするとglob_complete
(つまりsetopt glob_complete
、.zshrc
)次に入力できます。
子ブランチ *foo*Tab
*foo*
一致するブランチの名前(存在する場合)に置き換えられます。一致するブランチが複数ある場合は、一般(プレフィックス)完了と同じ種類のメニューまたはループ動作が発生します。