34

このような通常のgitコマンドを実行するとgit checkout、タブキーを押すとブランチ名のオートコンプリートが役立ちます。

ブランチ名をパラメーターとして受け取るgitエイリアスがいくつかありますが、ブランチ名のオートコンプリートをそれらで機能させる方法があるかどうか疑問に思っていますか?

編集:

コメントでの議論からいくつかの説明を提供するために、直接マッピングを使用したエイリアスは正常に機能します。

ci = commit
co = checkout

これは、もう少し複雑で$1、パラメータとして使用されないものです。たとえば、次のようになります。

tagarchive = !f() { git tag archive/$1 origin/$1 && git push origin :$1 && git push origin archive/$1 && git branch -d $1; }; f
4

2 に答える 2

37

git エイリアスの場合、git コマンドのオートコンプリート機能 ( __git()) は への呼び出しを使用してgit config --get "alias.$1"、同等のオートコンプリート機能を決定します。これは単純なマッピングでは機能しますが、より複雑なエイリアスでは機能しなくなります。

これを回避するには、エイリアスに一致する名前でオートコンプリート関数を定義します_git_tagarchive()。git のオートコンプリート機能は、それを取得してオートコンプリートに使用する必要があります。

例えば:

[me@home]$ git tagarchive <TAB><TAB>
AUTHORS             gentleSelect/       .gitignore          LICENSE             test_multiple.html  
cron/               .git/               index.html          README.md  
[me@home]$ _git_tagarchive() {
> _git_branch  # reuse that of git branch
> }
[me@home]$ git tagarchive  <TAB><TAB>
enable_multiple          master                   origin/gh-pages          v0.1                     v0.1.3 
FETCH_HEAD               ORIG_HEAD                origin/HEAD              v0.1.1                   v0.1.3.1 
HEAD                     origin/enable_multiple   origin/master            v0.1.2 

より永続的な解決策として、関数定義をbashrcファイルに追加するだけです。例えば:

_git_tagarchive() 
{
    _git_branch
}

のオートコンプリート機能を単に再利用したことに注意してくださいgit branch。これをより適切なものに変更したり、独自のものを作成したりすることができます。

より詳しい情報

このソリューションは、 の調査に基づいて特定されました/etc/bash_completion.d/git

通常、エイリアス化された git コマンドは__git_aliased_commands()、出力を解析しgit config --get "alias.$1"て使用するオートコンプリート機能を決定する関数によって処理されます。より複雑なシェル コマンドをエイリアス ターゲットとして使用すると、当然のことながら、このアプローチは無効になります。

さらに見てみると、サブコマンドのオートコンプリート機能の git ( _git()) チェーンのオートコンプリート機能は、関数の先頭に_git_(コマンド内のダッシュ ( -) をアンダースコアに置き換えて) 追加するだけで表示されます。これはチェックされる前に行わ__git_aliased_command()れるので、これは使用できるものです。

_git ()
{ 
   # .....
   local completion_func="_git_${command//-/_}"
   declare -f $completion_func >/dev/null && $completion_func && return

   local expansion=$(__git_aliased_command "$command")
   if [ -n "$expansion" ]; then
       completion_func="_git_${expansion//-/_}"
       declare -f $completion_func >/dev/null && $completion_func
   fi

}

したがって、私が行ったアプローチは、エイリアスに一致する関数が存在することを確認することです_git_tagarchive()

于 2012-07-13T11:08:15.593 に答える
4

2015 年 7 月の更新 (Git 2.5): では、git エイリアスを簡単に取得できcontrib/completion/git-completion.bashます。

commit 12bdc88commit e8f9e42 (2015 年 5 月 10 日) by SZEDER Gábor ( szeder)を参照してください。
( 2015 年 5 月 22 日、コミット 935d937Junio C Hamanoによってマージされました)gitster

~~~~~~~~~~~~~~

Git 2.1 (2014 年 8 月) では、Git 補完は複雑なエイリアスでより適切に機能するはずです。Steffen Prohaskaによるコミット 56f24e8
を 参照してください ( )sprohaska

補完: ' !f() { ... }; f' および " !sh -c '...' -" エイリアスを処理します

' !f() { ... }; f' と " !sh -c '....' -" は、より複雑なエイリアスを宣言するための推奨パターンです ( git wikiを参照)。
このコミットは、それらを処理するための補完を教えます。

エイリアスに使用する補完を決定するときに、左中括弧または単一引用符がスキップされ、git コマンドの検索が続行されるようになりました。
たとえば、エイリアス ' !f() { git commit ... }' または " !sh -c 'git commit ...'" はコミットの完了をトリガーするようになりました。
以前は、検索は左中かっこまたは引用符で停止し、補完はどのように補完するかを決定しようとしましたが、これは明らかに役に立ちませんでした。

nullコマンド ' 'は:スキップされるようになったため、目的の補完スタイルを宣言するための回避策として使用できます。

たとえば、エイリアスは次のとおりです。

!f() { : git commit ; if ... } f
!sh -c ': git commit; if ...' -

コミット完了をトリガーするようになりました。

シェル関数の宣言は、括弧の前にスペースがあってもなくても機能するようになりました。つまり、' !f() ...' と ' !f () ...' の両方が機能します。

于 2014-08-02T20:18:02.320 に答える