Рейтинг:3

Завершение Bash для веток git не работает после обновления до 21.10

флаг nl

Я не могу вспомнить, откуда я взял этот фрагмент сценария, но мой .bashrc содержит следующие строки:

# настроить автозаполнение для псевдонимов git
если [ -f "/usr/share/bash-completion/completions/git" ]; тогда
  источник /usr/share/bash-completion/completions/git
  __git_complete gc _git_checkout
  __git_complete gp _git_pull
еще
  echo "Ошибка загрузки дополнений git"
фи

git_branch () {
  ветка git 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}

gc и gp являются псевдонимами для git касса и git тянуть соответственно.

у меня есть /usr/share/bash-completion-completions/git поэтому, когда я источник ~/.bashrc в командной строке ничего не отображается.

До обновления до 21.10 (21.04, 20.04 и 18.04 работали нормально) я мог gc feat<tab><tab> и получить список ветвей, начинающихся с подвиг, но теперь я получаю странную ошибку после каждого <tab>:

$ gc featbash: [: -lt: ожидается унарный оператор // первая вкладка после 'gc feat'
bash: [: : ожидается целочисленное выражение
bash: [: -lt: ожидается унарный оператор
bash: [: -lt: ожидается унарный оператор
ure/bash: [: -lt: ожидается унарный оператор // вторая вкладка после 'ure/' (это было возвращено первой вкладкой)
bash: [: : ожидается целочисленное выражение
bash: [: -lt: ожидается унарный оператор
bash: [: -lt: ожидается унарный оператор // третья вкладка после этой строки
bash: [: -lt: ожидается унарный оператор
bash: [: : ожидается целочисленное выражение
bash: [: -lt: ожидается унарный оператор
bash: [: -lt: ожидается унарный оператор

Показать все 136 возможностей? (д или н)

Любая идея, что вызывает это?


ОБНОВЛЕНИЕ 1:

Я получаю эту ошибку только при использовании псевдонимов - завершение с использованием полной команды git checkout feat<tab> работает отлично. Когда я vim ~/.bash_aliases он предложил мне восстановить предыдущую версию и удалить файл подкачки. Это я сделал, и все выглядит нормально, но я все еще получаю сообщение об ошибке.


ОБНОВЛЕНИЕ 2:

Пробовал обновить, потом удалить/переустановить мерзавец и bash-завершение но безрезультатно.

bash-completion уже самая новая версия (1:2.11-2ubuntu1).
git уже самая новая версия (1:2.32.0-1ubuntu1).

ОБНОВЛЕНИЕ 3:

Сделал установить -xv чтобы включить подробный/отладочный. Ниже приведен не полный дамп, а часть, в которой создаются сообщения:

$ gc feat+ __git_func_wrap _git_checkout
+ местные слова cword prev
+ _get_comp_words_by_ref -n =: текущие слова cword пред.
+ флаг локального исключения i OPTIND=1
+ слова=()
+ местные слова-слова
+ упарг=()
+ upvars=()
+ локальные upargs upvars vcur vcword vprev vwords
+ getopts c:i:n:p:w: флаг -n =: cur слова cword пред.
+ case $флаг в
+ исключить==:
+ getopts c:i:n:p:w: флаг -n =: cur слова cword пред.
+ [[ 6 -ge 3 ]]
+ case ${!OPTIND} в
+ вкур=кур
+ (( ОПТИНД += 1 ))
+ [[ 6 -ge 4 ]]
+ case ${!OPTIND} в
+ vwords=слова
+ (( ОПТИНД += 1 ))
+ [[ 6 -ge 5 ]]
+ case ${!OPTIND} в
+ ключевое_слово=парное_слово
+ (( ОПТИНД += 1 ))
+ [[ 6 -ge 6 ]]
+ case ${!OPTIND} в
+ предыдущая = предыдущая
+ (( ОПТИНД += 1 ))
+ [[ 6 -ge 7 ]]
+ __get_cword_at_cursor_by_ref =: слова cword cur
+ слова=()
+ местные ключевые слова
+ __reassemble_comp_words_by_ref =: слова cword
+ местное исключение i j line ref
+ [[ -n =: ]]
+ исключить='[=:]'
+ printf -v ключевое слово %s 1
+ [[ -v исключить ]]
+ строка = 'gc подвиг'
+ (( я = 0, j = 0 ))
+ (( я < 2 ))
+ [[ 0 -gt 0 ]]
+ ссылка='слова[0]'
+ printf -v 'слова [0]' %s gc
+ строка = 'подвиг'
+ (( я == COMP_CWORD ))
+ ((я++, j++))
+ (( я < 2 ))
+ [[ 1 -gt 0 ]]
+ [[ подвиг == +([=:]) ]]
+ ссылка='слова[1]'
+ printf -v 'words[1]' %s подвиг
+ строка=
+ (( я == COMP_CWORD ))
+ printf -v ключевое слово %s 1
+ ((я++, j++))
+ (( я < 2 ))
+ (( я == COMP_CWORD ))
+ local i cur= index=7 'lead=gc feat'
+ [[ 7 -gt 0 ]]
+ [[ -n gc подвиг]]
+ [[ -n gcfeat ]]
+ cur='gc подвиг'
+ (( я = 0 ))
+ (( я <= ключевое слово ))
+ [[ 7 -ge 2 ]]
+ [[гк != \г\с ]]
+ (( я < слово ))
+ местный old_size=7
+ cur='подвиг'
+ локальный новый_размер=5
+ (( индекс -= старый_размер - новый_размер ))
+ ((++я))
+ (( я <= ключевое слово ))
+ [[ 5 -ge 4 ]]
+ [[ fea != \f\e\a\t ]]
+ кур = подвиг
+ (( индекс > 0 ))
+ (( индекс-- ))
+ [[ 4 -ge 4 ]]
+ [[ подвиг != \f\e\a\t ]]
+ (( я < слово ))
+ ((++я))
+ (( я <= ключевое слово ))
+ [[ -n подвиг ]]
+ [[ ! -н ​​подвиг]]
+ ((индекс <0))
+ местные слова cword cur
+ _upvars -a2 слова gc feat -v cword 1 -v cur feat
+ (( 10 ))
+ (( 10 ))
+ кейс $1 в
+ [[ -n 2 ]]
+ печать %d 2
+ [[ -n слов ]]
+ сбросить -v слова
+ eval 'слова=("${@:3:2}")'
слова = ("${@:3:2}")
++ слова=("${@:3:2}")
+ смена 4
+ (( 6 ))
+ кейс $1 в
+ [[ -n ключевое слово ]]
+ сбросить -v ключевое слово
+ оценка 'cword="$3"'
cword="$3"
++ ключевое слово=1
+ смена 3
+ (( 3 ))
+ кейс $1 в
+ [[ -n курс ]]
+ сбросить -v кур
+ оценка 'cur="$3"'
курс = "$3"
++ кур = подвиг
+ смена 3
+ (( 0 ))
+ [[ -v vcur ]]
+ upvars+=("$vcur")
+ upargs+=(-v $vcur "$cur")
+ [[ -v ключевое слово ]]
+ upvars+=("$vcword")
+ upargs+=(-v $vcword "$cword")
+ [[ -v назад ]]
+ [[ 1 -ge 1 ]]
+ upvars+=("$vprev")
+ upargs+=(-v $vprev "${words[cword - 1]}")
+ [[ -v слова ]]
+ upvars+=("$vwords")
+ upargs+=(-a${#words[@]} $vwords ${words+"${words[@]}"})
+ (( 4 ))
+ локальные прежние слова cur cword
+ _upvars -v cur feat -v cword 1 -v prev gc -a2 words gc feat
+ (( 13 ))
+ (( 13 ))
+ кейс $1 в
+ [[ -n курс ]]
+ сбросить -v кур
+ оценка 'cur="$3"'
курс = "$3"
++ кур = подвиг
+ смена 3
+ (( 10 ))
+ кейс $1 в
+ [[ -n ключевое слово ]]
+ сбросить -v ключевое слово
+ оценка 'cword="$3"'
cword="$3"
++ ключевое слово=1
+ смена 3
+ (( 7 ))
+ кейс $1 в
+ [[ -n предыд.]]
+ сбросить -v предыд.
+ оценка 'prev="$3"'
предыдущий = "$3"
++ предыд.=gc
+ смена 3
+ (( 4 ))
+ кейс $1 в
+ [[ -n 2 ]]
+ печать %d 2
+ [[ -n слов ]]
+ сбросить -v слова
+ eval 'слова=("${@:3:2}")'
слова = ("${@:3:2}")
++ слова=("${@:3:2}")
+ смена 4
+ (( 0 ))
+ _git_checkout
+ __git_has_doubledash
+ локальный с=1
+ '[' 1 -lt 1 ']'
+ возврат 1
++ __git_checkout_default_dwim_mode
++ локальный last_option dwim_opt=--dwim
++ '[' '' = 1 ']'
+++ __git_find_on_cmdline --no-track
+++ локальное слово c= show_idx
+++ тест 1 -gt 1
+++ локальный список слов=--без трека
+++ '[' -lt 1 ']'
bash: [: -lt: ожидается унарный оператор
++ '[' -n '' ']'
+++ __git config --type=bool checkout.guess
+++ git config --type=bool checkout.guess
++ '[' '' = ложь ']'
+++ __git_find_last_on_cmdline '--угадать --не-угадать'
+++ локальное слово c=1 show_idx
+++ тест 1 -gt 1
+++ локальный 'словарь=--догадка --не-догадка'
+++ '[' 1 -gt '' ']'
bash: [: : ожидается целочисленное выражение
++ последняя_опция=
++ случай "$last_option" в
++ эхо --dwim
+ локальный dwim_opt=--dwim
+ регистр "$prev" в
+ регистр "$cur" в
++ __git_find_on_cmdline '-b -B -d --detach --orphan'
++ локальное слово c= show_idx
++ тест 1 -gt 1
++ локальный 'словарь=-b -B -d --detach --orphan'
++ '[' -lt 1 ']'
bash: [: -lt: ожидается унарный оператор
+ '[' -n '' ']'
++ __git_find_on_cmdline --track
++ локальное слово c= show_idx
++ тест 1 -gt 1
++ локальный список слов=--трек
++ '[' -lt 1 ']'
bash: [: -lt: ожидается унарный оператор

Обратите внимание, что это не полный дамп, а только биты до того места, где генерируются сообщения об ошибках, включительно. Я попытался отследить одно из сообщений об ошибке через сценарий и нашел его в /usr/share/bash-completion/completions/git:

# Проверяем, присутствует ли одно из заданных слов в командной строке,
# и выведите первое найденное слово.
#
# Использование: __git_find_on_cmdline [<опция>]... "<список слов>"
# --show-idx: Опционально показать индекс найденного слова в массиве $words.
__git_find_on_cmdline()
{
        локальное слово c="$__git_cmd_idx" show_idx

        пока тест $# -gt 1; делать
                случай "$1" в
                --show-idx) show_idx=y ;;
                *) вернуть 1 ;;
                эсак
                сдвиг
        сделано
        местный список слов = "$1"

        в то время как [$c -lt $cword]; делать
                для слова в $wordlist; делать
                        если [ "$word" = "${words[c]}" ]; тогда
                                если [-n "${show_idx-}"]; тогда
                                        эхо "$c $слово"
                                еще
                                        эхо "$слово"
                                фи
                                возвращаться
                        фи
                сделано
                ((С++))
        сделано
}

Похоже, может быть, линия локальное слово c="$__git_cmd_idx" show_idx виноват, как с выглядит пустым для -lt сравнение позже при запуске ожидаемого унарного оператора.

Почему это перестало работать после обновления?

Рейтинг:4
флаг cn

Это было опубликовано как ошибка на GitHub завершения bash. Проблема решена в Гит 2.33.0.

Пока это исправление не попало в репозитории Ubuntu, вы можете найти обходной путь. следующее:

В файле /usr/share/bash-completion/completions/git, изменение

__git_func_wrap()
{
    local cur слова cword пред.

в

__git_func_wrap()
{
    локальные слова cur cword prev __git_cmd_idx=1

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.