Отключить автозаполнение удаленных веток в Git Bash?

Я работаю над довольно большим git-репо с несколькими тысячами (удаленных) веток. Я привык использовать автозаполнение (используя [TAB]) в консоли (в этом случае Git Bash), поэтому я неосознанно делаю это и для команд git.

например, я бы набрал

git checkout task[TAB]

с эффектом, что консоль глохнет на часто минуты. Есть ли способ ограничить автозаполнение только локальными филиалами?

7 ответов

Решение

С Git 2.13 (Q2 2017) вы можете отключить (частично) завершение ветки.

git checkout --no-guess ...
# or:
export GIT_COMPLETION_CHECKOUT_NO_GUESS=1

Смотрите коммит 60e71bb (21 апреля 2017 г.) Джеффа Кинга ( peff )
(Объединено Юнио С Хамано - gitster - в коммите b439747, 01 мая 2017 г.)

Как указано в contrib/completion/git-completion.bash сейчас:

Вы можете установить следующие переменные среды, чтобы влиять на поведение подпрограмм завершения:

GIT_COMPLETION_CHECKOUT_NO_GUESS

Если установлено значение "1", не включайте предложения "DWIM" в git-checkout завершение (например, завершение "foo", когда существует "origin/foo").

Примечание: DWIM - это сокращение от D O W I I MAN, где система пытается предвидеть, что пользователи намерены делать, исправляя тривиальные ошибки автоматически, а не слепо выполняя явные, но потенциально неверные вводы пользователей.

completion: опционально отключить оформление заказа DWIM

Когда мы завершаем имена филиалов для " git checkout ", мы также заполняем имена удаленных веток, которые могут вызвать поведение DWIM. В зависимости от вашего рабочего процесса и проекта это может быть удобным или раздражающим.

Например, мой клон gitster.git содержит 74 местных " jk/* "ветви, но происхождение содержит еще 147.
Когда я хочу оформить заказ в местном отделении, но не могу вспомнить название, вкладка завершения показывает мне 251 запись. И что еще хуже, для темы, которая была выбрана для pu, название вышестоящей ветки, вероятно, будет похоже на мое, что приведет к высокой вероятности, что я выберу неправильную и случайно создаю новую ветку.


Примечание: "подобрано за пу": посмотрите, что готовит в git.git: начинается с:

Коммиты с префиксом ' - "только в " pu ' (предлагаемые обновления), а коммиты с префиксом' + ' находятся в ' next ".

Это часть процесса Git Workflow Graduation.

pu (предлагаемые обновления) - это ветка интеграции для вещей, которые еще не совсем готовы для включения


Этот патч добавляет пользователю способ сообщить коду завершения не включать предложения DWIM для проверки.
Это уже можно сделать, набрав:

git checkout --no-guess jk/<TAB>

но это довольно громоздко

Недостатком, конечно, является то, что вы больше не получаете поддержку завершения, когда вы действительно хотите вызвать поведение DWIM.
Но, в зависимости от вашего рабочего процесса, это не может быть большой потерей (например, в git.git я с большей вероятностью захочу отключиться, поэтому я бы набрал " git checkout origin/jk/<TAB> " тем не мение).

Я предполагаю, что вы используете git-completion.bash сценарий, и что вы заботитесь только о git checkout,

Для этого я просто изменил одну строку в определении _git_checkout () функция в git-completion.bash:

<       __gitcomp_nl "$(__git_refs '' $track)"
---
>       __gitcomp_nl "$(__git_heads '' $track)"

Насколько я понимаю, это влияет только на действие завершения табуляции (из-за его расположения в * регистр оператора switch-case).

Если вы установили git-extension через homebrew, он находится здесь:/usr/local/etc/bash_completion.d/git-completion.bash

Следуя ответу erik.weathers выше, я внес следующие изменения, чтобы автозаполнение могло работать как для локальных, так и для удаленных на основе текущего префикса. По умолчанию он будет искать только локально, но если я укажу origin/… он будет знать, что я хочу искать удаленные ветви тоже.

в _git_checkout () метод, изменение

    __gitcomp_nl "$(__git_refs '' $track)"

чтобы:

    # only search local branches instead of remote branches if origin isn't specified
    if [[ $cur == "origin/"* ]]; then
        __gitcomp_nl "$(__git_refs '' $track)"
    else
        __gitcomp_nl "$(__git_heads '' $track)"
    fi

Конечно, вы можете изменить origin к чему-то другому, или вы можете выполнить поиск по списку удаленных префиксов, если у вас больше 1.

Вы можете взломать /etc/bash_completion.d/git

Вам нужно будет отредактировать __git_refs ()

Обратите внимание, что изменение в поведении будет применяться везде, где это возможно (так что даже с git push / pull там, где вы этого не захотите). Вы можете, конечно, сделать копию функции или передать дополнительный параметр, но я оставляю это вам

Вы могли бы подумать, что вы просто местные филиалы с псевдонимом co и все ветви с полной командой checkout,

Вы могли бы выполнить следующее. В вашем.bashrc вы переопределяете _git_checkout() функция. Вы оставляете эту функцию неизменной, кроме конца:

if [ $command -eq "co" ]; then
  __gitcomp "$(__git_refs_local '' $track)"
else
  __gitcomp "$(__git_refs '' $track)"
fi

Затем вам просто нужно определить новую функцию, __git_refs_localгде вы удалите удаленный материал.

Кэри Меткалф написал сообщение в блоге, содержащее решение, которое также редактирует функцию автозаполнения, но с немного более новым кодом, чем другие ответы. Он также определяет псевдоним checkoutr это сохраняет старое поведение автозаполнения на случай, если оно когда-либо понадобится.

Короче, сначала создайте checkoutr псевдоним с этой командой:

git config --global alias.checkoutr checkout

Тогда найди git-completion.bashскопируйте _git_checkout функция в RC-файл вашей оболочки, чтобы он был переопределен, и внутри этой функции замените эту строку:

__git_complete_refs $track_opt

со следующими строками:

if [ "$command" = "checkoutr" ]; then
    __git_complete_refs $track_opt
else
    __gitcomp_direct "$(__git_heads "" "$cur" " ")"
fi

Смотрите сообщение в блоге для более подробной информации и потенциальных обновлений кода.

Изменение $(brew --prefix)/etc/bash_completion.d/git-completion.bash не очень хорошая идея, потому что она будет перезаписываться при каждом обновлении Git через Homebrew.

Объединяя все ответы, я перезаписываю только _git_checkout функция из файла завершения в моем .bash_profile после поиска файла завершения:

_git_checkout ()
{
  __git_has_doubledash && return

  case "$cur" in
    --conflict=*)
      __gitcomp "diff3 merge" "" "${cur##--conflict=}"
      ;;
    --*)
      __gitcomp "
      --quiet --ours --theirs --track --no-track --merge
      --conflict= --orphan --patch
      "
      ;;
    *)
      # check if --track, --no-track, or --no-guess was specified
      # if so, disable DWIM mode
      local flags="--track --no-track --no-guess" track=1
      if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
        track=''
      fi
      # only search local branches instead of remote branches if origin isn't
      # specified
      if [[ $cur == "origin/"* ]]; then
        __gitcomp_nl "$(__git_refs '' $track)"
      else
        __gitcomp_nl "$(__git_heads '' $track)"
      fi
      ;;
  esac
}

Я не использую Git Bash сам, но если это то же самое, что упомянуто в http://tekrat.com/2008/04/30/bash-autocompletion-git-super-lazy-goodness/, вы должны быть в состоянии замените ветку git -a на обычную ветку git в

_complete_git() {
  if [ -d .git ]; then
    branches=`git branch -a | cut -c 3-`
    tags=`git tag`
    cur="${COMP_WORDS[COMP_CWORD]}"
    COMPREPLY=( $(compgen -W "${branches} ${tags}" -- ${cur}) )
  fi
}
complete -F _complete_git git checkout

(в вашем.profile или подобном) и получите то, что вы хотите.

FWW - это взлом __git_complete_refs, который помогает

__git_complete_refs ()

{локальный удаленный трек pfx cur _ = "$ cur" sfx = ""

while test $# != 0; do
    case "$1" in
    --remote=*) remote="${1##--remote=}" ;;
    --track)    track="yes" ;;
    --pfx=*)    pfx="${1##--pfx=}" ;;
    --cur=*)    cur_="${1##--cur=}" ;;
    --sfx=*)    sfx="${1##--sfx=}" ;;
    *)      return 1 ;;
    esac
    shift
done
echo cur_ $cur_ > a
 if [[  $GIT_COMPLETION_CHECKOUT_NO_GUESS != 1 || $cur_ == "origin"* ]]; then
    __gitcomp_direct "$(__git_refs "$remote" "$track" "$pfx" "$cur_" "$sfx")"
  else
    __gitcomp_direct "$(__git_heads  "" "$cur_")"
  fi

}

Другие вопросы по тегам