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

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

например. Я бы напечатал

git checkout task[TAB]

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

Ответ 1

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

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

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

Как теперь contrib/completion/git-completion.bash в contrib/completion/git-completion.bash:

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

GIT_COMPLETION_CHECKOUT_NO_GUESS

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

Примечание: DWIM является аббревиатурой D Пита шляпой I M ЕАН, где система пытается предугадать, что пользователи намерены делать, исправлять тривиальные ошибки автоматически, а не явные, но потенциально неверные входы слепо - исполнителей пользователей.

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

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

Например, мой клон gitster.git содержит 74 локальных ветки " jk/* ", но origin содержит еще 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> ").

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Ответ 4

Если вы установили git -completion через 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.

Ответ 5

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

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

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

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

Ответ 6

Изменение $(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
}

Ответ 7

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

_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 или аналогичном) и получите то, что вы хотите.

Ответ 8

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

Короче говоря, сначала создайте псевдоним checkoutr с помощью этой команды:

git config --global alias.checkoutr checkout

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

__git_complete_refs $track_opt

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

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

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