Git автозаповнення в псевдонімах bash?


84

Я використовую goяк простий псевдонім bash для git checkout branchname. Те, чого я сумую, - це функція автозаповнення, яка працює з повною git checkout branchna...командою, але не в псевдонімі.

Чи є спосіб доручити Башу "успадкувати" драйвер автозаповнення для іншої команди?




Пов’язане: якщо псевдонім встановлює спеціальний, git-dirвикористовуйте це .
user202729

Відповіді:


47

Якщо ви можете дізнатись функцію завершення, яка використовується оригінальною командою, ви можете призначити її псевдоніму за допомогою complete -F.

Наприклад, у моєму вікні ubuntu функція завершення, яку використовує, git checkoutє _git_checkout(знайдено в /etc/bash_complete.d/git).

Приклад

Перед запуском complete -F:

[me@home]$ git checkout <TAB><TAB>
HEAD            master          origin/HEAD     origin/master

[me@home]$ alias go="git checkout"

[me@home]$$ go <TAB><TAB>
.git/                precommit_config.py  README.md            SvnSentinel/         
.gitignore           precommit.py         startcommit.py       tests/ 

Після:

[me@home]$$ complete -F _git_checkout go

[me@home]$$ go <TAB><TAB>
HEAD            master          origin/HEAD     origin/master 

1
на ubuntu 12.04 завершення, здається, живуть у: /etc/bash_completion.d/git, а не /etc/bash_complete.d/git
Макс

8
Якщо у вас complete -Fне виходить, див. Відповідь __git_completeнижче stackoverflow.com/a/24665529/3779
Стів Клей

100

Після використання complete -F:

complete -F _git_checkout go

Вкладки після goможуть призвести до:

bash: [: 1: unary operator expected

Замість complete, використовуйте__git_complete

Для цього є вбудованою функцією завершення git bash.

Після оголошення псевдоніма прив’яжіть до нього правильну функцію автозаповнення:

alias g="git"
__git_complete g _git

alias go="git checkout"
__git_complete go _git_checkout

alias gp="git push"
__git_complete gp _git_push

4
@ LưuVĩnhPhúc У мене була та сама проблема. Це було тому, що у мене була __git_completeфункція в моєму пакеті завершення bash (встановленому за допомогою homebrew with brew install bash-completion), який наразі не був отриманий у моєму профілі bash. Довелося додати цей рядок до ~ / .bash_profile:[ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion
jangosteve

1
Додавання __git_complete під git checkoutпсевдонімом спрацювало як шарм !!!
Раджараман,

2
Має бути __git_main, ні _git. Причиною _gitє лише зворотна сумісність, вона в основному __git_mainзагорнута.
FelipeC

19

На Ubuntu 18.04 (Bionic) працює наступне. Додати що - щось на зразок цього фрагмента (з вашими псевдонімами) в якій віддається перевага конфігурації Баша файл , наприклад .bashrc, .bash_aliases .bash_profile.

# define aliases
alias gc='git checkout'
alias gp='git pull'

# setup autocompletion
if [ -f "/usr/share/bash-completion/completions/git" ]; then
  source /usr/share/bash-completion/completions/git
  __git_complete gc _git_checkout
  __git_complete gp _git_pull
else
  echo "Error loading git completions"
fi

Загалом формат __git_completeдирективи такий:

__git_complete <YOUR ALIAS> _git_<GIT COMMAND NAME>

Це поєднує мудрість із існуючих відповідей в одній сучасній відповіді, дякую усім.


Я хотів би лише додати, що для сеансу лише ssh / терміналу помістіть все в .bashrc. У мене були git complete речі в .bash_profile та псевдоніми в .bashrc, і я не міг змусити його працювати. Лише коли я додав echo "profile"/ echo "rc", я зрозумів це.
mtonc

18

В Ubuntu 16.04.3 LTS файл, який мені потрібен був джерелом /usr/share/bash-completion/completions/git. Отже в .bash_custom(або .bashrc, що завгодно):

[ -f /usr/share/bash-completion/completions/git ] && . /usr/share/bash-completion/completions/git
__git_complete g __git_main

1
Причиною необхідності ручного завантаження є те, що в даний час Bash завантажує ці файли динамічно. Поки що це завантажує їх відповідно до їх імені. Файл не буде завантажений, поки ви не досягнете завершення Git, що занадто пізно на час .bashrcпрочитання.
Франклін Ю

2

Додамо до інших чудових відповідей: зазвичай у вас багато псевдонімів Git, і може бути нудно вручну пересилати завершення для всіх них. Ось невеликий фокус, щоб зробити це автоматично:

if [ -f "/usr/share/bash-completion/completions/git" ]; then
  # Enable Git completions for aliases
  . /usr/share/bash-completion/completions/git
  for a in $(alias | sed -n 's/^alias \(g[^=]*\)=.git .*/\1/p'); do
    c=$(alias $a | sed 's/^[^=]*=.git \([a-z0-9\-]\+\).*/\1/' | tr '-' '_')
    if set | grep -q "^_git_$c *()"; then
      eval "__git_complete $a _git_$c"
    fi
  done
fi

1

У Linux Mint це не спрацювало для мене. Я отримувавbash: [: 1: unary operator expected .

Я виявив, що наступна відповідь спрацювала досить добре - з розділом з усунення несправностей, який надав користувач, був дуже корисним. /superuser/436314/how-can-i-get-bash-to-perform-tab-completion-for-my-aliases


1

Для macOS, виконайте наступне, щоб встановити завершення bash

 brew install bash-completion

Потім додайте наступне

[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh" 

до вашого .bashrc або .bash_profile


1

На Ubuntu 20.04 я додаю це в ~/.bashrc

source /usr/share/bash-completion/completions/git
alias g='git'
__git_complete g _git
alias go='git checkout'
__git_complete go _git_checkout

1

Як хтось інший відповів, вам слід використовувати __git_complete, інакше сценарій не вдасться.

alias g="git"
__git_complete g __git_main

alias g="gl"
__git_complete gl _git_log

Але ви не повинні використовувати _gitдля головної команди, це__git_main .

На жаль, багато інформації про завершення приховано, але ви можете дізнатись більше в README мого форка: git-complete .


0

Я розумію, що ви спеціально запитуєте про псевдоніми bash, але для тих, хто приходить сюди і шукає автозаповнення в bash для складних псевдонімів git, дивіться тут .

Зокрема:

# If you use complex aliases of form '!f() { ... }; f', you can use the null
# command ':' as the first command in the function body to declare the desired
# completion style.  For example '!f() { : git commit ; ... }; f' will
# tell the completion to use commit completion.  This also works with aliases
# of form "!sh -c '...'".  For example, "!sh -c ': git commit ; ... '".
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.