사용자 도구

사이트 도구


windows:git_bash

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
windows:git_bash [2024/02/12 02:13] – [Git Bash 사용하기] taekguwindows:git_bash [2025/04/15 10:05] (현재) – 바깥 편집 127.0.0.1
줄 1: 줄 1:
 +======= Git Bash 사용하기 =======
  
 +https://git-scm.com/downloads에서 윈도우용 git을 받으면 git bash가 같이 설치되는데 아주 편리하다.
 +
 +윈도우 WSL보다 더 편리한 것같다.
 +하지만 Linux에서 bash,zsh를 사용할 때처럼 window의 git bash로 쓰고 싶은데 windows는 동일하게 작동하지 않는다.
 +
 +참조
 +  * [[https://violetboralee.medium.com/windows-%EC%82%AC%EC%9A%A9%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-git-bash-%EC%84%A4%EC%A0%95-ac50acb34c46|Windows 사용자를 위한 Git Bash 설정]]
 +  * https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
 +  * https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
 +
 +=== ls시 그룹명이 표현 하도록 하기 ===
 +파일을 편집 C:\Program Files\Git\etc\nsswitch.conf하고 다음 줄을 변경합니다.
 +<code conf>
 +group: files # db
 +->
 +group: files db
 +</code>
 +이렇게 하면 시스템이 /etc/group파일(" files ")과 기본 Windows 파일 시스템(" db ") 모두에서 그룹 정보를 확인할 수 있습니다. (원래 버전에서는 " db " 옵션이 주석 처리되어 운영체제를 확인하지 않습니다.)
 +
 +그러면 다음과 같은 출력을 얻게 됩니다 ls -l.
 +<code bash>
 +-rw-r--r-- 1 JoelFan Domain Users  8774 Aug 13  2021 README.md
 +</code>
 +====== 편리하게 사용하기 위해서 설정하는 것들 ======
 +다운로드 (사용자홈에 받는다.)
 +  * [[https://www.garamx.com/dokuwiki/doku.php?id=windows:git_bash#git-completionbash|git-completetion.bash]]
 +  * [[https://www.garamx.com/dokuwiki/doku.php?id=windows:git_bash#git-promptsh|git-prompt.sh]]
 +
 +적당히 .bash_profile, .bashrc수정
 +
 +<code bash .bash_profile>
 +# Enable tab completion
 +source ~/git-completion.bash
 +
 +# setting Colors!
 +green="\[\033[0;32m\]"
 +blue="\[\033[0;34m\]"
 +purple="\[\033[0;35m\]"
 +reset="\[\033[0m\]"
 +
 +# Change command prompt
 +source ~/git-prompt.sh
 +export GIT_PS1_SHOWDIRTYSTATE=1
 +# 위 코드는 repository에 변경이 있는 경우, 상태에 따라 *나 + 기호가 표시되도록 해줍니다.
 +# unstaged 변경: *
 +# staged 변경: +
 +
 +# setopt PROMPT_SUBST
 +# MacOS ZSH에서는 PROMPT_SUBST설정
 +
 +export PS1="$purple\u@\h$green\$(__git_ps1)$blue \w $reset $ "
 +
 +# generated by Git for Windows
 +test -f ~/.profile && . ~/.profile
 +test -f ~/.bashrc && . ~/.bashrc
 +</code>
 +
 +
 +==== git-completion.bash ====
 +
 +<code bash git-completion.bash>
 +# bash/zsh completion support for core Git.
 +#
 +# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
 +# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
 +# Distributed under the GNU General Public License, version 2.0.
 +#
 +# The contained completion routines provide support for completing:
 +#
 +#    *) local and remote branch names
 +#    *) local and remote tag names
 +#    *) .git/remotes file names
 +#    *) git 'subcommands'
 +#    *) git email aliases for git-send-email
 +#    *) tree paths within 'ref:path/to/file' expressions
 +#    *) file paths within current working directory and index
 +#    *) common --long-options
 +#
 +# To use these routines:
 +#
 +#    1) Copy this file to somewhere (e.g. ~/.git-completion.bash).
 +#    2) Add the following line to your .bashrc/.zshrc:
 +#        source ~/.git-completion.bash
 +#    3) Consider changing your PS1 to also show the current branch,
 +#       see git-prompt.sh for details.
 +#
 +# 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 ; ... '".
 +# Note that "git" is optional --- '!f() { : commit; ...}; f' would complete
 +# just like the 'git commit' command.
 +#
 +# If you have a command that is not part of git, but you would still
 +# like completion, you can use __git_complete:
 +#
 +#   __git_complete gl git_log
 +#
 +# Or if it's a main command (i.e. git or gitk):
 +#
 +#   __git_complete gk gitk
 +#
 +# Compatible with bash 3.2.57.
 +#
 +# You can set the following environment variables to influence the behavior of
 +# the completion routines:
 +#
 +#   GIT_COMPLETION_CHECKOUT_NO_GUESS
 +#
 +#     When set to "1", do not include "DWIM" suggestions in git-checkout
 +#     and git-switch completion (e.g., completing "foo" when "origin/foo"
 +#     exists).
 +#
 +#   GIT_COMPLETION_SHOW_ALL_COMMANDS
 +#
 +#     When set to "1" suggest all commands, including plumbing commands
 +#     which are hidden by default (e.g. "cat-file" on "git ca<TAB>").
 +#
 +#   GIT_COMPLETION_SHOW_ALL
 +#
 +#     When set to "1" suggest all options, including options which are
 +#     typically hidden (e.g. '--allow-empty' for 'git commit').
 +#
 +#   GIT_COMPLETION_IGNORE_CASE
 +#
 +#     When set, uses for-each-ref '--ignore-case' to find refs that match
 +#     case insensitively, even on systems with case sensitive file systems
 +#     (e.g., completing tag name "FOO" on "git checkout f<TAB>").
 +
 +case "$COMP_WORDBREAKS" in
 +*:*) : great ;;
 +*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
 +esac
 +
 +# Discovers the path to the git repository taking any '--git-dir=<path>' and
 +# '-C <path>' options into account and stores it in the $__git_repo_path
 +# variable.
 +__git_find_repo_path ()
 +{
 + if [ -n "${__git_repo_path-}" ]; then
 + # we already know where it is
 + return
 + fi
 +
 + if [ -n "${__git_C_args-}" ]; then
 + __git_repo_path="$(git "${__git_C_args[@]}" \
 + ${__git_dir:+--git-dir="$__git_dir"} \
 + rev-parse --absolute-git-dir 2>/dev/null)"
 + elif [ -n "${__git_dir-}" ]; then
 + test -d "$__git_dir" &&
 + __git_repo_path="$__git_dir"
 + elif [ -n "${GIT_DIR-}" ]; then
 + test -d "$GIT_DIR" &&
 + __git_repo_path="$GIT_DIR"
 + elif [ -d .git ]; then
 + __git_repo_path=.git
 + else
 + __git_repo_path="$(git rev-parse --git-dir 2>/dev/null)"
 + fi
 +}
 +
 +# Deprecated: use __git_find_repo_path() and $__git_repo_path instead
 +# __gitdir accepts 0 or 1 arguments (i.e., location)
 +# returns location of .git repo
 +__gitdir ()
 +{
 + if [ -z "${1-}" ]; then
 + __git_find_repo_path || return 1
 + echo "$__git_repo_path"
 + elif [ -d "$1/.git" ]; then
 + echo "$1/.git"
 + else
 + echo "$1"
 + fi
 +}
 +
 +# Runs git with all the options given as argument, respecting any
 +# '--git-dir=<path>' and '-C <path>' options present on the command line
 +__git ()
 +{
 + git ${__git_C_args:+"${__git_C_args[@]}"} \
 + ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null
 +}
 +
 +# Helper function to read the first line of a file into a variable.
 +# __git_eread requires 2 arguments, the file path and the name of the
 +# variable, in that order.
 +#
 +# This is taken from git-prompt.sh.
 +__git_eread ()
 +{
 + test -r "$1" && IFS=$'\r\n' read -r "$2" <"$1"
 +}
 +
 +# Runs git in $__git_repo_path to determine whether a pseudoref exists.
 +# 1: The pseudo-ref to search
 +__git_pseudoref_exists ()
 +{
 + local ref=$1
 + local head
 +
 + __git_find_repo_path
 +
 + # If the reftable is in use, we have to shell out to 'git rev-parse'
 + # to determine whether the ref exists instead of looking directly in
 + # the filesystem to determine whether the ref exists. Otherwise, use
 + # Bash builtins since executing Git commands are expensive on some
 + # platforms.
 + if __git_eread "$__git_repo_path/HEAD" head; then
 + if [ "$head" == "ref: refs/heads/.invalid" ]; then
 + __git show-ref --exists "$ref"
 + return $?
 + fi
 + fi
 +
 + [ -f "$__git_repo_path/$ref" ]
 +}
 +
 +# Removes backslash escaping, single quotes and double quotes from a word,
 +# stores the result in the variable $dequoted_word.
 +# 1: The word to dequote.
 +__git_dequote ()
 +{
 + local rest="$1" len ch
 +
 + dequoted_word=""
 +
 + while test -n "$rest"; do
 + len=${#dequoted_word}
 + dequoted_word="$dequoted_word${rest%%[\\\'\"]*}"
 + rest="${rest:$((${#dequoted_word}-$len))}"
 +
 + case "${rest:0:1}" in
 + \\)
 + ch="${rest:1:1}"
 + case "$ch" in
 + $'\n')
 + ;;
 + *)
 + dequoted_word="$dequoted_word$ch"
 + ;;
 + esac
 + rest="${rest:2}"
 + ;;
 + \')
 + rest="${rest:1}"
 + len=${#dequoted_word}
 + dequoted_word="$dequoted_word${rest%%\'*}"
 + rest="${rest:$((${#dequoted_word}-$len+1))}"
 + ;;
 + \")
 + rest="${rest:1}"
 + while test -n "$rest" ; do
 + len=${#dequoted_word}
 + dequoted_word="$dequoted_word${rest%%[\\\"]*}"
 + rest="${rest:$((${#dequoted_word}-$len))}"
 + case "${rest:0:1}" in
 + \\)
 + ch="${rest:1:1}"
 + case "$ch" in
 + \"|\\|\$|\`)
 + dequoted_word="$dequoted_word$ch"
 + ;;
 + $'\n')
 + ;;
 + *)
 + dequoted_word="$dequoted_word\\$ch"
 + ;;
 + esac
 + rest="${rest:2}"
 + ;;
 + \")
 + rest="${rest:1}"
 + break
 + ;;
 + esac
 + done
 + ;;
 + esac
 + done
 +}
 +
 +# The following function is based on code from:
 +#
 +#   bash_completion - programmable completion functions for bash 3.2+
 +#
 +#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
 +#             © 2009-2010, Bash Completion Maintainers
 +#                     <bash-completion-devel@lists.alioth.debian.org>
 +#
 +#   This program is free software; you can redistribute it and/or modify
 +#   it under the terms of the GNU General Public License as published by
 +#   the Free Software Foundation; either version 2, or (at your option)
 +#   any later version.
 +#
 +#   This program is distributed in the hope that it will be useful,
 +#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +#   GNU General Public License for more details.
 +#
 +#   You should have received a copy of the GNU General Public License
 +#   along with this program; if not, see <http://www.gnu.org/licenses/>.
 +#
 +#   The latest version of this software can be obtained here:
 +#
 +#   http://bash-completion.alioth.debian.org/
 +#
 +#   RELEASE: 2.x
 +
 +# This function can be used to access a tokenized list of words
 +# on the command line:
 +#
 +# __git_reassemble_comp_words_by_ref '=:'
 +# if test "${words_[cword_-1]}" = -w
 +# then
 +# ...
 +# fi
 +#
 +# The argument should be a collection of characters from the list of
 +# word completion separators (COMP_WORDBREAKS) to treat as ordinary
 +# characters.
 +#
 +# This is roughly equivalent to going back in time and setting
 +# COMP_WORDBREAKS to exclude those characters.  The intent is to
 +# make option types like --date=<type> and <rev>:<path> easy to
 +# recognize by treating each shell word as a single token.
 +#
 +# It is best not to set COMP_WORDBREAKS directly because the value is
 +# shared with other completion scripts.  By the time the completion
 +# function gets called, COMP_WORDS has already been populated so local
 +# changes to COMP_WORDBREAKS have no effect.
 +#
 +# Output: words_, cword_, cur_.
 +
 +__git_reassemble_comp_words_by_ref()
 +{
 + local exclude i j first
 + # Which word separators to exclude?
 + exclude="${1//[^$COMP_WORDBREAKS]}"
 + cword_=$COMP_CWORD
 + if [ -z "$exclude" ]; then
 + words_=("${COMP_WORDS[@]}")
 + return
 + fi
 + # List of word completion separators has shrunk;
 + # re-assemble words to complete.
 + for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
 + # Append each nonempty word consisting of just
 + # word separator characters to the current word.
 + first=t
 + while
 + [ $i -gt 0 ] &&
 + [ -n "${COMP_WORDS[$i]}" ] &&
 + # word consists of excluded word separators
 + [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
 + do
 + # Attach to the previous token,
 + # unless the previous token is the command name.
 + if [ $j -ge 2 ] && [ -n "$first" ]; then
 + ((j--))
 + fi
 + first=
 + words_[$j]=${words_[j]}${COMP_WORDS[i]}
 + if [ $i = $COMP_CWORD ]; then
 + cword_=$j
 + fi
 + if (($i < ${#COMP_WORDS[@]} - 1)); then
 + ((i++))
 + else
 + # Done.
 + return
 + fi
 + done
 + words_[$j]=${words_[j]}${COMP_WORDS[i]}
 + if [ $i = $COMP_CWORD ]; then
 + cword_=$j
 + fi
 + done
 +}
 +
 +if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
 +_get_comp_words_by_ref ()
 +{
 + local exclude cur_ words_ cword_
 + if [ "$1" = "-n" ]; then
 + exclude=$2
 + shift 2
 + fi
 + __git_reassemble_comp_words_by_ref "$exclude"
 + cur_=${words_[cword_]}
 + while [ $# -gt 0 ]; do
 + case "$1" in
 + cur)
 + cur=$cur_
 + ;;
 + prev)
 + prev=${words_[$cword_-1]}
 + ;;
 + words)
 + words=("${words_[@]}")
 + ;;
 + cword)
 + cword=$cword_
 + ;;
 + esac
 + shift
 + done
 +}
 +fi
 +
 +# Fills the COMPREPLY array with prefiltered words without any additional
 +# processing.
 +# Callers must take care of providing only words that match the current word
 +# to be completed and adding any prefix and/or suffix (trailing space!), if
 +# necessary.
 +# 1: List of newline-separated matching completion words, complete with
 +#    prefix and suffix.
 +__gitcomp_direct ()
 +{
 + local IFS=$'\n'
 +
 + COMPREPLY=($1)
 +}
 +
 +# Similar to __gitcomp_direct, but appends to COMPREPLY instead.
 +# Callers must take care of providing only words that match the current word
 +# to be completed and adding any prefix and/or suffix (trailing space!), if
 +# necessary.
 +# 1: List of newline-separated matching completion words, complete with
 +#    prefix and suffix.
 +__gitcomp_direct_append ()
 +{
 + local IFS=$'\n'
 +
 + COMPREPLY+=($1)
 +}
 +
 +__gitcompappend ()
 +{
 + local x i=${#COMPREPLY[@]}
 + for x in $1; do
 + if [[ "$x" == "$3"* ]]; then
 + COMPREPLY[i++]="$2$x$4"
 + fi
 + done
 +}
 +
 +__gitcompadd ()
 +{
 + COMPREPLY=()
 + __gitcompappend "$@"
 +}
 +
 +# Generates completion reply, appending a space to possible completion words,
 +# if necessary.
 +# It accepts 1 to 4 arguments:
 +# 1: List of possible completion words.
 +# 2: A prefix to be added to each possible completion word (optional).
 +# 3: Generate possible completion matches for this word (optional).
 +# 4: A suffix to be appended to each possible completion word (optional).
 +__gitcomp ()
 +{
 + local cur_="${3-$cur}"
 +
 + case "$cur_" in
 + *=)
 + ;;
 + --no-*)
 + local c i=0 IFS=$' \t\n'
 + for c in $1; do
 + if [[ $c == "--" ]]; then
 + continue
 + fi
 + c="$c${4-}"
 + if [[ $c == "$cur_"* ]]; then
 + case $c in
 + --*=|*.) ;;
 + *) c="$c " ;;
 + esac
 + COMPREPLY[i++]="${2-}$c"
 + fi
 + done
 + ;;
 + *)
 + local c i=0 IFS=$' \t\n'
 + for c in $1; do
 + if [[ $c == "--" ]]; then
 + c="--no-...${4-}"
 + if [[ $c == "$cur_"* ]]; then
 + COMPREPLY[i++]="${2-}$c "
 + fi
 + break
 + fi
 + c="$c${4-}"
 + if [[ $c == "$cur_"* ]]; then
 + case $c in
 + *=|*.) ;;
 + *) c="$c " ;;
 + esac
 + COMPREPLY[i++]="${2-}$c"
 + fi
 + done
 + ;;
 + esac
 +}
 +
 +# Clear the variables caching builtins' options when (re-)sourcing
 +# the completion script.
 +if [[ -n ${ZSH_VERSION-} ]]; then
 + unset ${(M)${(k)parameters[@]}:#__gitcomp_builtin_*} 2>/dev/null
 +else
 + unset $(compgen -v __gitcomp_builtin_)
 +fi
 +
 +# This function is equivalent to
 +#
 +#    __gitcomp "$(git xxx --git-completion-helper) ..."
 +#
 +# except that the output is cached. Accept 1-3 arguments:
 +# 1: the git command to execute, this is also the cache key
 +# 2: extra options to be added on top (e.g. negative forms)
 +# 3: options to be excluded
 +__gitcomp_builtin ()
 +{
 + # spaces must be replaced with underscore for multi-word
 + # commands, e.g. "git remote add" becomes remote_add.
 + local cmd="$1"
 + local incl="${2-}"
 + local excl="${3-}"
 +
 + local var=__gitcomp_builtin_"${cmd//-/_}"
 + local options
 + eval "options=\${$var-}"
 +
 + if [ -z "$options" ]; then
 + local completion_helper
 + if [ "${GIT_COMPLETION_SHOW_ALL-}" = "1" ]; then
 + completion_helper="--git-completion-helper-all"
 + else
 + completion_helper="--git-completion-helper"
 + fi
 + # leading and trailing spaces are significant to make
 + # option removal work correctly.
 + options=" $incl $(__git ${cmd/_/ } $completion_helper) " || return
 +
 + for i in $excl; do
 + options="${options/ $i / }"
 + done
 + eval "$var=\"$options\""
 + fi
 +
 + __gitcomp "$options"
 +}
 +
 +# Variation of __gitcomp_nl () that appends to the existing list of
 +# completion candidates, COMPREPLY.
 +__gitcomp_nl_append ()
 +{
 + local IFS=$'\n'
 + __gitcompappend "$1" "${2-}" "${3-$cur}" "${4- }"
 +}
 +
 +# Generates completion reply from newline-separated possible completion words
 +# by appending a space to all of them.
 +# It accepts 1 to 4 arguments:
 +# 1: List of possible completion words, separated by a single newline.
 +# 2: A prefix to be added to each possible completion word (optional).
 +# 3: Generate possible completion matches for this word (optional).
 +# 4: A suffix to be appended to each possible completion word instead of
 +#    the default space (optional).  If specified but empty, nothing is
 +#    appended.
 +__gitcomp_nl ()
 +{
 + COMPREPLY=()
 + __gitcomp_nl_append "$@"
 +}
 +
 +# Fills the COMPREPLY array with prefiltered paths without any additional
 +# processing.
 +# Callers must take care of providing only paths that match the current path
 +# to be completed and adding any prefix path components, if necessary.
 +# 1: List of newline-separated matching paths, complete with all prefix
 +#    path components.
 +__gitcomp_file_direct ()
 +{
 + local IFS=$'\n'
 +
 + COMPREPLY=($1)
 +
 + # use a hack to enable file mode in bash < 4
 + compopt -o filenames +o nospace 2>/dev/null ||
 + compgen -f /non-existing-dir/ >/dev/null ||
 + true
 +}
 +
 +# Generates completion reply with compgen from newline-separated possible
 +# completion filenames.
 +# It accepts 1 to 3 arguments:
 +# 1: List of possible completion filenames, separated by a single newline.
 +# 2: A directory prefix to be added to each possible completion filename
 +#    (optional).
 +# 3: Generate possible completion matches for this word (optional).
 +__gitcomp_file ()
 +{
 + local IFS=$'\n'
 +
 + # XXX does not work when the directory prefix contains a tilde,
 + # since tilde expansion is not applied.
 + # This means that COMPREPLY will be empty and Bash default
 + # completion will be used.
 + __gitcompadd "$1" "${2-}" "${3-$cur}" ""
 +
 + # use a hack to enable file mode in bash < 4
 + compopt -o filenames +o nospace 2>/dev/null ||
 + compgen -f /non-existing-dir/ >/dev/null ||
 + true
 +}
 +
 +# Execute 'git ls-files', unless the --committable option is specified, in
 +# which case it runs 'git diff-index' to find out the files that can be
 +# committed.  It return paths relative to the directory specified in the first
 +# argument, and using the options specified in the second argument.
 +__git_ls_files_helper ()
 +{
 + if [ "$2" = "--committable" ]; then
 + __git -C "$1" -c core.quotePath=false diff-index \
 + --name-only --relative HEAD -- "${3//\\/\\\\}*"
 + else
 + # NOTE: $2 is not quoted in order to support multiple options
 + __git -C "$1" -c core.quotePath=false ls-files \
 + --exclude-standard $2 -- "${3//\\/\\\\}*"
 + fi
 +}
 +
 +
 +# __git_index_files accepts 1 or 2 arguments:
 +# 1: Options to pass to ls-files (required).
 +# 2: A directory path (optional).
 +#    If provided, only files within the specified directory are listed.
 +#    Sub directories are never recursed.  Path must have a trailing
 +#    slash.
 +# 3: List only paths matching this path component (optional).
 +__git_index_files ()
 +{
 + local root="$2" match="$3"
 +
 + __git_ls_files_helper "$root" "$1" "${match:-?}" |
 + awk -F / -v pfx="${2//\\/\\\\}" '{
 + paths[$1] = 1
 + }
 + END {
 + for (p in paths) {
 + if (substr(p, 1, 1) != "\"") {
 + # No special characters, easy!
 + print pfx p
 + continue
 + }
 +
 + # The path is quoted.
 + p = dequote(p)
 + if (p == "")
 + continue
 +
 + # Even when a directory name itself does not contain
 + # any special characters, it will still be quoted if
 + # any of its (stripped) trailing path components do.
 + # Because of this we may have seen the same directory
 + # both quoted and unquoted.
 + if (p in paths)
 + # We have seen the same directory unquoted,
 + # skip it.
 + continue
 + else
 + print pfx p
 + }
 + }
 + function dequote(p,    bs_idx, out, esc, esc_idx, dec) {
 + # Skip opening double quote.
 + p = substr(p, 2)
 +
 + # Interpret backslash escape sequences.
 + while ((bs_idx = index(p, "\\")) != 0) {
 + out = out substr(p, 1, bs_idx - 1)
 + esc = substr(p, bs_idx + 1, 1)
 + p = substr(p, bs_idx + 2)
 +
 + if ((esc_idx = index("abtvfr\"\\", esc)) != 0) {
 + # C-style one-character escape sequence.
 + out = out substr("\a\b\t\v\f\r\"\\",
 + esc_idx, 1)
 + } else if (esc == "n") {
 + # Uh-oh, a newline character.
 + # We cannot reliably put a pathname
 + # containing a newline into COMPREPLY,
 + # and the newline would create a mess.
 + # Skip this path.
 + return ""
 + } else {
 + # Must be a \nnn octal value, then.
 + dec = esc             * 64 + \
 +       substr(p, 1, 1) * 8  + \
 +       substr(p, 2, 1)
 + out = out sprintf("%c", dec)
 + p = substr(p, 3)
 + }
 + }
 + # Drop closing double quote, if there is one.
 + # (There is not any if this is a directory, as it was
 + # already stripped with the trailing path components.)
 + if (substr(p, length(p), 1) == "\"")
 + out = out substr(p, 1, length(p) - 1)
 + else
 + out = out p
 +
 + return out
 + }'
 +}
 +
 +# __git_complete_index_file requires 1 argument:
 +# 1: the options to pass to ls-file
 +#
 +# The exception is --committable, which finds the files appropriate commit.
 +__git_complete_index_file ()
 +{
 + local dequoted_word pfx="" cur_
 +
 + __git_dequote "$cur"
 +
 + case "$dequoted_word" in
 + ?*/*)
 + pfx="${dequoted_word%/*}/"
 + cur_="${dequoted_word##*/}"
 + ;;
 + *)
 + cur_="$dequoted_word"
 + esac
 +
 + __gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")"
 +}
 +
 +# Lists branches from the local repository.
 +# 1: A prefix to be added to each listed branch (optional).
 +# 2: List only branches matching this word (optional; list all branches if
 +#    unset or empty).
 +# 3: A suffix to be appended to each listed branch (optional).
 +__git_heads ()
 +{
 + local pfx="${1-}" cur_="${2-}" sfx="${3-}"
 +
 + __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
 + ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
 + "refs/heads/$cur_*" "refs/heads/$cur_*/**"
 +}
 +
 +# Lists branches from remote repositories.
 +# 1: A prefix to be added to each listed branch (optional).
 +# 2: List only branches matching this word (optional; list all branches if
 +#    unset or empty).
 +# 3: A suffix to be appended to each listed branch (optional).
 +__git_remote_heads ()
 +{
 + local pfx="${1-}" cur_="${2-}" sfx="${3-}"
 +
 + __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
 + ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
 + "refs/remotes/$cur_*" "refs/remotes/$cur_*/**"
 +}
 +
 +# Lists tags from the local repository.
 +# Accepts the same positional parameters as __git_heads() above.
 +__git_tags ()
 +{
 + local pfx="${1-}" cur_="${2-}" sfx="${3-}"
 +
 + __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
 + ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
 + "refs/tags/$cur_*" "refs/tags/$cur_*/**"
 +}
 +
 +# List unique branches from refs/remotes used for 'git checkout' and 'git
 +# switch' tracking DWIMery.
 +# 1: A prefix to be added to each listed branch (optional)
 +# 2: List only branches matching this word (optional; list all branches if
 +#    unset or empty).
 +# 3: A suffix to be appended to each listed branch (optional).
 +__git_dwim_remote_heads ()
 +{
 + local pfx="${1-}" cur_="${2-}" sfx="${3-}"
 + local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
 +
 + # employ the heuristic used by git checkout and git switch
 + # Try to find a remote branch that cur_es the completion word
 + # but only output if the branch name is unique
 + __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
 + --sort="refname:strip=3" \
 + ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
 + "refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \
 + uniq -u
 +}
 +
 +# Lists refs from the local (by default) or from a remote repository.
 +# It accepts 0, 1 or 2 arguments:
 +# 1: The remote to list refs from (optional; ignored, if set but empty).
 +#    Can be the name of a configured remote, a path, or a URL.
 +# 2: In addition to local refs, list unique branches from refs/remotes/ for
 +#    'git checkout's tracking DWIMery (optional; ignored, if set but empty).
 +# 3: A prefix to be added to each listed ref (optional).
 +# 4: List only refs matching this word (optional; list all refs if unset or
 +#    empty).
 +# 5: A suffix to be appended to each listed ref (optional; ignored, if set
 +#    but empty).
 +#
 +# Use __git_complete_refs() instead.
 +__git_refs ()
 +{
 + local i hash dir track="${2-}"
 + local list_refs_from=path remote="${1-}"
 + local format refs
 + local pfx="${3-}" cur_="${4-$cur}" sfx="${5-}"
 + local match="${4-}"
 + local umatch="${4-}"
 + local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
 +
 + __git_find_repo_path
 + dir="$__git_repo_path"
 +
 + if [ -z "$remote" ]; then
 + if [ -z "$dir" ]; then
 + return
 + fi
 + else
 + if __git_is_configured_remote "$remote"; then
 + # configured remote takes precedence over a
 + # local directory with the same name
 + list_refs_from=remote
 + elif [ -d "$remote/.git" ]; then
 + dir="$remote/.git"
 + elif [ -d "$remote" ]; then
 + dir="$remote"
 + else
 + list_refs_from=url
 + fi
 + fi
 +
 + if test "${GIT_COMPLETION_IGNORE_CASE:+1}" = "1"
 + then
 + # uppercase with tr instead of ${match,^^} for bash 3.2 compatibility
 + umatch=$(echo "$match" | tr a-z A-Z 2>/dev/null || echo "$match")
 + fi
 +
 + if [ "$list_refs_from" = path ]; then
 + if [[ "$cur_" == ^* ]]; then
 + pfx="$pfx^"
 + fer_pfx="$fer_pfx^"
 + cur_=${cur_#^}
 + match=${match#^}
 + umatch=${umatch#^}
 + fi
 + case "$cur_" in
 + refs|refs/*)
 + format="refname"
 + refs=("$match*" "$match*/**")
 + track=""
 + ;;
 + *)
 + for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD CHERRY_PICK_HEAD REVERT_HEAD BISECT_HEAD AUTO_MERGE; do
 + case "$i" in
 + $match*|$umatch*)
 + if [ -e "$dir/$i" ]; then
 + echo "$pfx$i$sfx"
 + fi
 + ;;
 + esac
 + done
 + format="refname:strip=2"
 + refs=("refs/tags/$match*" "refs/tags/$match*/**"
 + "refs/heads/$match*" "refs/heads/$match*/**"
 + "refs/remotes/$match*" "refs/remotes/$match*/**")
 + ;;
 + esac
 + __git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \
 + ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
 + "${refs[@]}"
 + if [ -n "$track" ]; then
 + __git_dwim_remote_heads "$pfx" "$match" "$sfx"
 + fi
 + return
 + fi
 + case "$cur_" in
 + refs|refs/*)
 + __git ls-remote "$remote" "$match*" | \
 + while read -r hash i; do
 + case "$i" in
 + *^{}) ;;
 + *) echo "$pfx$i$sfx" ;;
 + esac
 + done
 + ;;
 + *)
 + if [ "$list_refs_from" = remote ]; then
 + case "HEAD" in
 + $match*|$umatch*) echo "${pfx}HEAD$sfx" ;;
 + esac
 + __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
 + ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
 + "refs/remotes/$remote/$match*" \
 + "refs/remotes/$remote/$match*/**"
 + else
 + local query_symref
 + case "HEAD" in
 + $match*|$umatch*) query_symref="HEAD" ;;
 + esac
 + __git ls-remote "$remote" $query_symref \
 + "refs/tags/$match*" "refs/heads/$match*" \
 + "refs/remotes/$match*" |
 + while read -r hash i; do
 + case "$i" in
 + *^{}) ;;
 + refs/*) echo "$pfx${i#refs/*/}$sfx" ;;
 + *) echo "$pfx$i$sfx" ;;  # symbolic refs
 + esac
 + done
 + fi
 + ;;
 + esac
 +}
 +
 +# Completes refs, short and long, local and remote, symbolic and pseudo.
 +#
 +# Usage: __git_complete_refs [<option>]...
 +# --remote=<remote>: The remote to list refs from, can be the name of a
 +#                    configured remote, a path, or a URL.
 +# --dwim: List unique remote branches for 'git switch's tracking DWIMery.
 +# --pfx=<prefix>: A prefix to be added to each ref.
 +# --cur=<word>: The current ref to be completed.  Defaults to the current
 +#               word to be completed.
 +# --sfx=<suffix>: A suffix to be appended to each ref instead of the default
 +#                 space.
 +# --mode=<mode>: What set of refs to complete, one of 'refs' (the default) to
 +#                complete all refs, 'heads' to complete only branches, or
 +#                'remote-heads' to complete only remote branches. Note that
 +#                --remote is only compatible with --mode=refs.
 +__git_complete_refs ()
 +{
 + local remote= dwim= pfx= cur_="$cur" sfx=" " mode="refs"
 +
 + while test $# != 0; do
 + case "$1" in
 + --remote=*) remote="${1##--remote=}" ;;
 + --dwim) dwim="yes" ;;
 + # --track is an old spelling of --dwim
 + --track) dwim="yes" ;;
 + --pfx=*) pfx="${1##--pfx=}" ;;
 + --cur=*) cur_="${1##--cur=}" ;;
 + --sfx=*) sfx="${1##--sfx=}" ;;
 + --mode=*) mode="${1##--mode=}" ;;
 + *) return 1 ;;
 + esac
 + shift
 + done
 +
 + # complete references based on the specified mode
 + case "$mode" in
 + refs)
 + __gitcomp_direct "$(__git_refs "$remote" "" "$pfx" "$cur_" "$sfx")" ;;
 + heads)
 + __gitcomp_direct "$(__git_heads "$pfx" "$cur_" "$sfx")" ;;
 + remote-heads)
 + __gitcomp_direct "$(__git_remote_heads "$pfx" "$cur_" "$sfx")" ;;
 + *)
 + return 1 ;;
 + esac
 +
 + # Append DWIM remote branch names if requested
 + if [ "$dwim" = "yes" ]; then
 + __gitcomp_direct_append "$(__git_dwim_remote_heads "$pfx" "$cur_" "$sfx")"
 + fi
 +}
 +
 +# __git_refs2 requires 1 argument (to pass to __git_refs)
 +# Deprecated: use __git_complete_fetch_refspecs() instead.
 +__git_refs2 ()
 +{
 + local i
 + for i in $(__git_refs "$1"); do
 + echo "$i:$i"
 + done
 +}
 +
 +# Completes refspecs for fetching from a remote repository.
 +# 1: The remote repository.
 +# 2: A prefix to be added to each listed refspec (optional).
 +# 3: The ref to be completed as a refspec instead of the current word to be
 +#    completed (optional)
 +# 4: A suffix to be appended to each listed refspec instead of the default
 +#    space (optional).
 +__git_complete_fetch_refspecs ()
 +{
 + local i remote="$1" pfx="${2-}" cur_="${3-$cur}" sfx="${4- }"
 +
 + __gitcomp_direct "$(
 + for i in $(__git_refs "$remote" "" "" "$cur_") ; do
 + echo "$pfx$i:$i$sfx"
 + done
 + )"
 +}
 +
 +# __git_refs_remotes requires 1 argument (to pass to ls-remote)
 +__git_refs_remotes ()
 +{
 + local i hash
 + __git ls-remote "$1" 'refs/heads/*' | \
 + while read -r hash i; do
 + echo "$i:refs/remotes/$1/${i#refs/heads/}"
 + done
 +}
 +
 +__git_remotes ()
 +{
 + __git_find_repo_path
 + test -d "$__git_repo_path/remotes" && ls -1 "$__git_repo_path/remotes"
 + __git remote
 +}
 +
 +# Returns true if $1 matches the name of a configured remote, false otherwise.
 +__git_is_configured_remote ()
 +{
 + local remote
 + for remote in $(__git_remotes); do
 + if [ "$remote" = "$1" ]; then
 + return 0
 + fi
 + done
 + return 1
 +}
 +
 +__git_list_merge_strategies ()
 +{
 + LANG=C LC_ALL=C git merge -s help 2>&1 |
 + sed -n -e '/[Aa]vailable strategies are: /,/^$/{
 + s/\.$//
 + s/.*://
 + s/^[ ]*//
 + s/[ ]*$//
 + p
 + }'
 +}
 +
 +__git_merge_strategies=
 +# 'git merge -s help' (and thus detection of the merge strategy
 +# list) fails, unfortunately, if run outside of any git working
 +# tree.  __git_merge_strategies is set to the empty string in
 +# that case, and the detection will be repeated the next time it
 +# is needed.
 +__git_compute_merge_strategies ()
 +{
 + test -n "$__git_merge_strategies" ||
 + __git_merge_strategies=$(__git_list_merge_strategies)
 +}
 +
 +__git_merge_strategy_options="ours theirs subtree subtree= patience
 + histogram diff-algorithm= ignore-space-change ignore-all-space
 + ignore-space-at-eol renormalize no-renormalize no-renames
 + find-renames find-renames= rename-threshold="
 +
 +__git_complete_revlist_file ()
 +{
 + local dequoted_word pfx ls ref cur_="$cur"
 + case "$cur_" in
 + *..?*:*)
 + return
 + ;;
 + ?*:*)
 + ref="${cur_%%:*}"
 + cur_="${cur_#*:}"
 +
 + __git_dequote "$cur_"
 +
 + case "$dequoted_word" in
 + ?*/*)
 + pfx="${dequoted_word%/*}"
 + cur_="${dequoted_word##*/}"
 + ls="$ref:$pfx"
 + pfx="$pfx/"
 + ;;
 + *)
 + cur_="$dequoted_word"
 + ls="$ref"
 + ;;
 + esac
 +
 + case "$COMP_WORDBREAKS" in
 + *:*) : great ;;
 + *)   pfx="$ref:$pfx" ;;
 + esac
 +
 + __gitcomp_file "$(__git ls-tree "$ls" \
 + | sed 's/^.* //
 +        s/$//')" \
 + "$pfx" "$cur_"
 + ;;
 + *...*)
 + pfx="${cur_%...*}..."
 + cur_="${cur_#*...}"
 + __git_complete_refs --pfx="$pfx" --cur="$cur_"
 + ;;
 + *..*)
 + pfx="${cur_%..*}.."
 + cur_="${cur_#*..}"
 + __git_complete_refs --pfx="$pfx" --cur="$cur_"
 + ;;
 + *)
 + __git_complete_refs
 + ;;
 + esac
 +}
 +
 +__git_complete_file ()
 +{
 + __git_complete_revlist_file
 +}
 +
 +__git_complete_revlist ()
 +{
 + __git_complete_revlist_file
 +}
 +
 +__git_complete_remote_or_refspec ()
 +{
 + local cur_="$cur" cmd="${words[__git_cmd_idx]}"
 + local i c=$((__git_cmd_idx+1)) remote="" pfx="" lhs=1 no_complete_refspec=0
 + if [ "$cmd" = "remote" ]; then
 + ((c++))
 + fi
 + while [ $c -lt $cword ]; do
 + i="${words[c]}"
 + case "$i" in
 + --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
 + -d|--delete) [ "$cmd" = "push" ] && lhs=0 ;;
 + --all)
 + case "$cmd" in
 + push) no_complete_refspec=1 ;;
 + fetch)
 + return
 + ;;
 + *) ;;
 + esac
 + ;;
 + --multiple) no_complete_refspec=1; break ;;
 + -*) ;;
 + *) remote="$i"; break ;;
 + esac
 + ((c++))
 + done
 + if [ -z "$remote" ]; then
 + __gitcomp_nl "$(__git_remotes)"
 + return
 + fi
 + if [ $no_complete_refspec = 1 ]; then
 + return
 + fi
 + [ "$remote" = "." ] && remote=
 + case "$cur_" in
 + *:*)
 + case "$COMP_WORDBREAKS" in
 + *:*) : great ;;
 + *)   pfx="${cur_%%:*}:" ;;
 + esac
 + cur_="${cur_#*:}"
 + lhs=0
 + ;;
 + +*)
 + pfx="+"
 + cur_="${cur_#+}"
 + ;;
 + esac
 + case "$cmd" in
 + fetch)
 + if [ $lhs = 1 ]; then
 + __git_complete_fetch_refspecs "$remote" "$pfx" "$cur_"
 + else
 + __git_complete_refs --pfx="$pfx" --cur="$cur_"
 + fi
 + ;;
 + pull|remote)
 + if [ $lhs = 1 ]; then
 + __git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
 + else
 + __git_complete_refs --pfx="$pfx" --cur="$cur_"
 + fi
 + ;;
 + push)
 + if [ $lhs = 1 ]; then
 + __git_complete_refs --pfx="$pfx" --cur="$cur_"
 + else
 + __git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
 + fi
 + ;;
 + esac
 +}
 +
 +__git_complete_strategy ()
 +{
 + __git_compute_merge_strategies
 + case "$prev" in
 + -s|--strategy)
 + __gitcomp "$__git_merge_strategies"
 + return 0
 + ;;
 + -X)
 + __gitcomp "$__git_merge_strategy_options"
 + return 0
 + ;;
 + esac
 + case "$cur" in
 + --strategy=*)
 + __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
 + return 0
 + ;;
 + --strategy-option=*)
 + __gitcomp "$__git_merge_strategy_options" "" "${cur##--strategy-option=}"
 + return 0
 + ;;
 + esac
 + return 1
 +}
 +
 +__git_all_commands=
 +__git_compute_all_commands ()
 +{
 + test -n "$__git_all_commands" ||
 + __git_all_commands=$(__git --list-cmds=main,others,alias,nohelpers)
 +}
 +
 +# Lists all set config variables starting with the given section prefix,
 +# with the prefix removed.
 +__git_get_config_variables ()
 +{
 + local section="$1" i IFS=$'\n'
 + for i in $(__git config --name-only --get-regexp "^$section\..*"); do
 + echo "${i#$section.}"
 + done
 +}
 +
 +__git_pretty_aliases ()
 +{
 + __git_get_config_variables "pretty"
 +}
 +
 +# __git_aliased_command requires 1 argument
 +__git_aliased_command ()
 +{
 + local cur=$1 last list= word cmdline
 +
 + while [[ -n "$cur" ]]; do
 + if [[ "$list" == *" $cur "* ]]; then
 + # loop detected
 + return
 + fi
 +
 + cmdline=$(__git config --get "alias.$cur")
 + list=" $cur $list"
 + last=$cur
 + cur=
 +
 + for word in $cmdline; do
 + case "$word" in
 + \!gitk|gitk)
 + cur="gitk"
 + break
 + ;;
 + \!*) : shell command alias ;;
 + -*) : option ;;
 + *=*) : setting env ;;
 + git) : git itself ;;
 + \(\))   : skip parens of shell function definition ;;
 + {) : skip start of shell helper function ;;
 + :) : skip null command ;;
 + \'*) : skip opening quote after sh -c ;;
 + *)
 + cur="${word%;}"
 + break
 + esac
 + done
 + done
 +
 + cur=$last
 + if [[ "$cur" != "$1" ]]; then
 + echo "$cur"
 + fi
 +}
 +
 +# Check whether one of the given words is present on the command line,
 +# and print the first word found.
 +#
 +# Usage: __git_find_on_cmdline [<option>]... "<wordlist>"
 +# --show-idx: Optionally show the index of the found word in the $words array.
 +__git_find_on_cmdline ()
 +{
 + local word c="$__git_cmd_idx" show_idx
 +
 + while test $# -gt 1; do
 + case "$1" in
 + --show-idx) show_idx=y ;;
 + *) return 1 ;;
 + esac
 + shift
 + done
 + local wordlist="$1"
 +
 + while [ $c -lt $cword ]; do
 + for word in $wordlist; do
 + if [ "$word" = "${words[c]}" ]; then
 + if [ -n "${show_idx-}" ]; then
 + echo "$c $word"
 + else
 + echo "$word"
 + fi
 + return
 + fi
 + done
 + ((c++))
 + done
 +}
 +
 +# Similar to __git_find_on_cmdline, except that it loops backwards and thus
 +# prints the *last* word found. Useful for finding which of two options that
 +# supersede each other came last, such as "--guess" and "--no-guess".
 +#
 +# Usage: __git_find_last_on_cmdline [<option>]... "<wordlist>"
 +# --show-idx: Optionally show the index of the found word in the $words array.
 +__git_find_last_on_cmdline ()
 +{
 + local word c=$cword show_idx
 +
 + while test $# -gt 1; do
 + case "$1" in
 + --show-idx) show_idx=y ;;
 + *) return 1 ;;
 + esac
 + shift
 + done
 + local wordlist="$1"
 +
 + while [ $c -gt "$__git_cmd_idx" ]; do
 + ((c--))
 + for word in $wordlist; do
 + if [ "$word" = "${words[c]}" ]; then
 + if [ -n "$show_idx" ]; then
 + echo "$c $word"
 + else
 + echo "$word"
 + fi
 + return
 + fi
 + done
 + done
 +}
 +
 +# Echo the value of an option set on the command line or config
 +#
 +# $1: short option name
 +# $2: long option name including =
 +# $3: list of possible values
 +# $4: config string (optional)
 +#
 +# example:
 +# result="$(__git_get_option_value "-d" "--do-something=" \
 +#     "yes no" "core.doSomething")"
 +#
 +# result is then either empty (no option set) or "yes" or "no"
 +#
 +# __git_get_option_value requires 3 arguments
 +__git_get_option_value ()
 +{
 + local c short_opt long_opt val
 + local result= values config_key word
 +
 + short_opt="$1"
 + long_opt="$2"
 + values="$3"
 + config_key="$4"
 +
 + ((c = $cword - 1))
 + while [ $c -ge 0 ]; do
 + word="${words[c]}"
 + for val in $values; do
 + if [ "$short_opt$val" = "$word" ] ||
 +    [ "$long_opt$val"  = "$word" ]; then
 + result="$val"
 + break 2
 + fi
 + done
 + ((c--))
 + done
 +
 + if [ -n "$config_key" ] && [ -z "$result" ]; then
 + result="$(__git config "$config_key")"
 + fi
 +
 + echo "$result"
 +}
 +
 +__git_has_doubledash ()
 +{
 + local c=1
 + while [ $c -lt $cword ]; do
 + if [ "--" = "${words[c]}" ]; then
 + return 0
 + fi
 + ((c++))
 + done
 + return 1
 +}
 +
 +# Try to count non option arguments passed on the command line for the
 +# specified git command.
 +# When options are used, it is necessary to use the special -- option to
 +# tell the implementation were non option arguments begin.
 +# XXX this can not be improved, since options can appear everywhere, as
 +# an example:
 +# git mv x -n y
 +#
 +# __git_count_arguments requires 1 argument: the git command executed.
 +__git_count_arguments ()
 +{
 + local word i c=0
 +
 + # Skip "git" (first argument)
 + for ((i=$__git_cmd_idx; i < ${#words[@]}; i++)); do
 + word="${words[i]}"
 +
 + case "$word" in
 + --)
 + # Good; we can assume that the following are only non
 + # option arguments.
 + ((c = 0))
 + ;;
 + "$1")
 + # Skip the specified git command and discard git
 + # main options
 + ((c = 0))
 + ;;
 + ?*)
 + ((c++))
 + ;;
 + esac
 + done
 +
 + printf "%d" $c
 +}
 +
 +__git_whitespacelist="nowarn warn error error-all fix"
 +__git_patchformat="mbox stgit stgit-series hg mboxrd"
 +__git_showcurrentpatch="diff raw"
 +__git_am_inprogress_options="--skip --continue --resolved --abort --quit --show-current-patch"
 +__git_quoted_cr="nowarn warn strip"
 +
 +_git_am ()
 +{
 + __git_find_repo_path
 + if [ -d "$__git_repo_path"/rebase-apply ]; then
 + __gitcomp "$__git_am_inprogress_options"
 + return
 + fi
 + case "$cur" in
 + --whitespace=*)
 + __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 + return
 + ;;
 + --patch-format=*)
 + __gitcomp "$__git_patchformat" "" "${cur##--patch-format=}"
 + return
 + ;;
 + --show-current-patch=*)
 + __gitcomp "$__git_showcurrentpatch" "" "${cur##--show-current-patch=}"
 + return
 + ;;
 + --quoted-cr=*)
 + __gitcomp "$__git_quoted_cr" "" "${cur##--quoted-cr=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin am "" \
 + "$__git_am_inprogress_options"
 + return
 + esac
 +}
 +
 +_git_apply ()
 +{
 + case "$cur" in
 + --whitespace=*)
 + __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin apply
 + return
 + esac
 +}
 +
 +_git_add ()
 +{
 + case "$cur" in
 + --chmod=*)
 + __gitcomp "+x -x" "" "${cur##--chmod=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin add
 + return
 + esac
 +
 + local complete_opt="--others --modified --directory --no-empty-directory"
 + if test -n "$(__git_find_on_cmdline "-u --update")"
 + then
 + complete_opt="--modified"
 + fi
 + __git_complete_index_file "$complete_opt"
 +}
 +
 +_git_archive ()
 +{
 + case "$cur" in
 + --format=*)
 + __gitcomp "$(git archive --list)" "" "${cur##--format=}"
 + return
 + ;;
 + --remote=*)
 + __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin archive "--format= --list --verbose --prefix= --worktree-attributes"
 + return
 + ;;
 + esac
 + __git_complete_file
 +}
 +
 +_git_bisect ()
 +{
 + __git_has_doubledash && return
 +
 + local subcommands="start bad good skip reset visualize replay log run"
 + local subcommand="$(__git_find_on_cmdline "$subcommands")"
 + if [ -z "$subcommand" ]; then
 + __git_find_repo_path
 + if [ -f "$__git_repo_path"/BISECT_START ]; then
 + __gitcomp "$subcommands"
 + else
 + __gitcomp "replay start"
 + fi
 + return
 + fi
 +
 + case "$subcommand" in
 + bad|good|reset|skip|start)
 + __git_complete_refs
 + ;;
 + *)
 + ;;
 + esac
 +}
 +
 +__git_ref_fieldlist="refname objecttype objectsize objectname upstream push HEAD symref"
 +
 +_git_branch ()
 +{
 + local i c="$__git_cmd_idx" only_local_ref="n" has_r="n"
 +
 + while [ $c -lt $cword ]; do
 + i="${words[c]}"
 + case "$i" in
 + -d|-D|--delete|-m|-M|--move|-c|-C|--copy)
 + only_local_ref="y" ;;
 + -r|--remotes)
 + has_r="y" ;;
 + esac
 + ((c++))
 + done
 +
 + case "$cur" in
 + --set-upstream-to=*)
 + __git_complete_refs --cur="${cur##--set-upstream-to=}"
 + ;;
 + --*)
 + __gitcomp_builtin branch
 + ;;
 + *)
 + if [ $only_local_ref = "y" -a $has_r = "n" ]; then
 + __gitcomp_direct "$(__git_heads "" "$cur" " ")"
 + else
 + __git_complete_refs
 + fi
 + ;;
 + esac
 +}
 +
 +_git_bundle ()
 +{
 + local cmd="${words[__git_cmd_idx+1]}"
 + case "$cword" in
 + $((__git_cmd_idx+1)))
 + __gitcomp "create list-heads verify unbundle"
 + ;;
 + $((__git_cmd_idx+2)))
 + # looking for a file
 + ;;
 + *)
 + case "$cmd" in
 + create)
 + __git_complete_revlist
 + ;;
 + esac
 + ;;
 + esac
 +}
 +
 +# Helper function to decide whether or not we should enable DWIM logic for
 +# git-switch and git-checkout.
 +#
 +# To decide between the following rules in decreasing priority order:
 +# - the last provided of "--guess" or "--no-guess" explicitly enable or
 +#   disable completion of DWIM logic respectively.
 +# - If checkout.guess is false, disable completion of DWIM logic.
 +# - If the --no-track option is provided, take this as a hint to disable the
 +#   DWIM completion logic
 +# - If GIT_COMPLETION_CHECKOUT_NO_GUESS is set, disable the DWIM completion
 +#   logic, as requested by the user.
 +# - Enable DWIM logic otherwise.
 +#
 +__git_checkout_default_dwim_mode ()
 +{
 + local last_option dwim_opt="--dwim"
 +
 + if [ "${GIT_COMPLETION_CHECKOUT_NO_GUESS-}" = "1" ]; then
 + dwim_opt=""
 + fi
 +
 + # --no-track disables DWIM, but with lower priority than
 + # --guess/--no-guess/checkout.guess
 + if [ -n "$(__git_find_on_cmdline "--no-track")" ]; then
 + dwim_opt=""
 + fi
 +
 + # checkout.guess = false disables DWIM, but with lower priority than
 + # --guess/--no-guess
 + if [ "$(__git config --type=bool checkout.guess)" = "false" ]; then
 + dwim_opt=""
 + fi
 +
 + # Find the last provided --guess or --no-guess
 + last_option="$(__git_find_last_on_cmdline "--guess --no-guess")"
 + case "$last_option" in
 + --guess)
 + dwim_opt="--dwim"
 + ;;
 + --no-guess)
 + dwim_opt=""
 + ;;
 + esac
 +
 + echo "$dwim_opt"
 +}
 +
 +_git_checkout ()
 +{
 + __git_has_doubledash && return
 +
 + local dwim_opt="$(__git_checkout_default_dwim_mode)"
 +
 + case "$prev" in
 + -b|-B|--orphan)
 + # Complete local branches (and DWIM branch
 + # remote branch names) for an option argument
 + # specifying a new branch name. This is for
 + # convenience, assuming new branches are
 + # possibly based on pre-existing branch names.
 + __git_complete_refs $dwim_opt --mode="heads"
 + return
 + ;;
 + *)
 + ;;
 + esac
 +
 + case "$cur" in
 + --conflict=*)
 + __gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
 + ;;
 + --*)
 + __gitcomp_builtin checkout
 + ;;
 + *)
 + # At this point, we've already handled special completion for
 + # the arguments to -b/-B, and --orphan. There are 3 main
 + # things left we can possibly complete:
 + # 1) a start-point for -b/-B, -d/--detach, or --orphan
 + # 2) a remote head, for --track
 + # 3) an arbitrary reference, possibly including DWIM names
 + #
 +
 + if [ -n "$(__git_find_on_cmdline "-b -B -d --detach --orphan")" ]; then
 + __git_complete_refs --mode="refs"
 + elif [ -n "$(__git_find_on_cmdline "-t --track")" ]; then
 + __git_complete_refs --mode="remote-heads"
 + else
 + __git_complete_refs $dwim_opt --mode="refs"
 + fi
 + ;;
 + esac
 +}
 +
 +__git_sequencer_inprogress_options="--continue --quit --abort --skip"
 +
 +__git_cherry_pick_inprogress_options=$__git_sequencer_inprogress_options
 +
 +_git_cherry_pick ()
 +{
 + if __git_pseudoref_exists CHERRY_PICK_HEAD; then
 + __gitcomp "$__git_cherry_pick_inprogress_options"
 + return
 + fi
 +
 + __git_complete_strategy && return
 +
 + case "$cur" in
 + --*)
 + __gitcomp_builtin cherry-pick "" \
 + "$__git_cherry_pick_inprogress_options"
 + ;;
 + *)
 + __git_complete_refs
 + ;;
 + esac
 +}
 +
 +_git_clean ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin clean
 + return
 + ;;
 + esac
 +
 + # XXX should we check for -x option ?
 + __git_complete_index_file "--others --directory"
 +}
 +
 +_git_clone ()
 +{
 + case "$prev" in
 + -c|--config)
 + __git_complete_config_variable_name_and_value
 + return
 + ;;
 + esac
 + case "$cur" in
 + --config=*)
 + __git_complete_config_variable_name_and_value \
 + --cur="${cur##--config=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin clone
 + return
 + ;;
 + esac
 +}
 +
 +__git_untracked_file_modes="all no normal"
 +
 +__git_trailer_tokens ()
 +{
 + __git config --name-only --get-regexp '^trailer\..*\.key$' | cut -d. -f 2- | rev | cut -d. -f2- | rev
 +}
 +
 +_git_commit ()
 +{
 + case "$prev" in
 + -c|-C)
 + __git_complete_refs
 + return
 + ;;
 + esac
 +
 + case "$cur" in
 + --cleanup=*)
 + __gitcomp "default scissors strip verbatim whitespace
 + " "" "${cur##--cleanup=}"
 + return
 + ;;
 + --reuse-message=*|--reedit-message=*|\
 + --fixup=*|--squash=*)
 + __git_complete_refs --cur="${cur#*=}"
 + return
 + ;;
 + --untracked-files=*)
 + __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
 + return
 + ;;
 + --trailer=*)
 + __gitcomp_nl "$(__git_trailer_tokens)" "" "${cur##--trailer=}" ":"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin commit
 + return
 + esac
 +
 + if __git rev-parse --verify --quiet HEAD >/dev/null; then
 + __git_complete_index_file "--committable"
 + else
 + # This is the first commit
 + __git_complete_index_file "--cached"
 + fi
 +}
 +
 +_git_describe ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin describe
 + return
 + esac
 + __git_complete_refs
 +}
 +
 +__git_diff_algorithms="myers minimal patience histogram"
 +
 +__git_diff_submodule_formats="diff log short"
 +
 +__git_color_moved_opts="no default plain blocks zebra dimmed-zebra"
 +
 +__git_color_moved_ws_opts="no ignore-space-at-eol ignore-space-change
 + ignore-all-space allow-indentation-change"
 +
 +__git_ws_error_highlight_opts="context old new all default"
 +
 +# Options for the diff machinery (diff, log, show, stash, range-diff, ...)
 +__git_diff_common_options="--stat --numstat --shortstat --summary
 + --patch-with-stat --name-only --name-status --color
 + --no-color --color-words --no-renames --check
 + --color-moved --color-moved= --no-color-moved
 + --color-moved-ws= --no-color-moved-ws
 + --full-index --binary --abbrev --diff-filter=
 + --find-copies --find-object --find-renames
 + --no-relative --relative
 + --find-copies-harder --ignore-cr-at-eol
 + --text --ignore-space-at-eol --ignore-space-change
 + --ignore-all-space --ignore-blank-lines --exit-code
 + --quiet --ext-diff --no-ext-diff --unified=
 + --no-prefix --src-prefix= --dst-prefix=
 + --inter-hunk-context= --function-context
 + --patience --histogram --minimal
 + --raw --word-diff --word-diff-regex=
 + --dirstat --dirstat= --dirstat-by-file
 + --dirstat-by-file= --cumulative
 + --diff-algorithm= --default-prefix
 + --submodule --submodule= --ignore-submodules
 + --indent-heuristic --no-indent-heuristic
 + --textconv --no-textconv --break-rewrites
 + --patch --no-patch --cc --combined-all-paths
 + --anchored= --compact-summary --ignore-matching-lines=
 + --irreversible-delete --line-prefix --no-stat
 + --output= --output-indicator-context=
 + --output-indicator-new= --output-indicator-old=
 + --ws-error-highlight=
 + --pickaxe-all --pickaxe-regex --patch-with-raw
 +"
 +
 +# Options for diff/difftool
 +__git_diff_difftool_options="--cached --staged
 + --base --ours --theirs --no-index --merge-base
 + --ita-invisible-in-index --ita-visible-in-index
 + $__git_diff_common_options"
 +
 +_git_diff ()
 +{
 + __git_has_doubledash && return
 +
 + case "$cur" in
 + --diff-algorithm=*)
 + __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
 + return
 + ;;
 + --submodule=*)
 + __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
 + return
 + ;;
 + --color-moved=*)
 + __gitcomp "$__git_color_moved_opts" "" "${cur##--color-moved=}"
 + return
 + ;;
 + --color-moved-ws=*)
 + __gitcomp "$__git_color_moved_ws_opts" "" "${cur##--color-moved-ws=}"
 + return
 + ;;
 + --ws-error-highlight=*)
 + __gitcomp "$__git_ws_error_highlight_opts" "" "${cur##--ws-error-highlight=}"
 + return
 + ;;
 + --*)
 + __gitcomp "$__git_diff_difftool_options"
 + return
 + ;;
 + esac
 + __git_complete_revlist_file
 +}
 +
 +__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
 + tkdiff vimdiff nvimdiff gvimdiff xxdiff araxis p4merge
 + bc codecompare smerge
 +"
 +
 +_git_difftool ()
 +{
 + __git_has_doubledash && return
 +
 + case "$cur" in
 + --tool=*)
 + __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin difftool "$__git_diff_difftool_options"
 + return
 + ;;
 + esac
 + __git_complete_revlist_file
 +}
 +
 +__git_fetch_recurse_submodules="yes on-demand no"
 +
 +_git_fetch ()
 +{
 + case "$cur" in
 + --recurse-submodules=*)
 + __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
 + return
 + ;;
 + --filter=*)
 + __gitcomp "blob:none blob:limit= sparse:oid=" "" "${cur##--filter=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin fetch
 + return
 + ;;
 + esac
 + __git_complete_remote_or_refspec
 +}
 +
 +__git_format_patch_extra_options="
 + --full-index --not --all --no-prefix --src-prefix=
 + --dst-prefix= --notes
 +"
 +
 +_git_format_patch ()
 +{
 + case "$cur" in
 + --thread=*)
 + __gitcomp "
 + deep shallow
 + " "" "${cur##--thread=}"
 + return
 + ;;
 + --base=*|--interdiff=*|--range-diff=*)
 + __git_complete_refs --cur="${cur#--*=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin format-patch "$__git_format_patch_extra_options"
 + return
 + ;;
 + esac
 + __git_complete_revlist
 +}
 +
 +_git_fsck ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin fsck
 + return
 + ;;
 + esac
 +}
 +
 +_git_gitk ()
 +{
 + __gitk_main
 +}
 +
 +# Lists matching symbol names from a tag (as in ctags) file.
 +# 1: List symbol names matching this word.
 +# 2: The tag file to list symbol names from.
 +# 3: A prefix to be added to each listed symbol name (optional).
 +# 4: A suffix to be appended to each listed symbol name (optional).
 +__git_match_ctag () {
 + awk -v pfx="${3-}" -v sfx="${4-}" "
 + /^${1//\//\\/}/ { print pfx \$1 sfx }
 + " "$2"
 +}
 +
 +# Complete symbol names from a tag file.
 +# Usage: __git_complete_symbol [<option>]...
 +# --tags=<file>: The tag file to list symbol names from instead of the
 +#                default "tags".
 +# --pfx=<prefix>: A prefix to be added to each symbol name.
 +# --cur=<word>: The current symbol name to be completed.  Defaults to
 +#               the current word to be completed.
 +# --sfx=<suffix>: A suffix to be appended to each symbol name instead
 +#                 of the default space.
 +__git_complete_symbol () {
 + local tags=tags pfx="" cur_="${cur-}" sfx=" "
 +
 + while test $# != 0; do
 + case "$1" in
 + --tags=*) tags="${1##--tags=}" ;;
 + --pfx=*) pfx="${1##--pfx=}" ;;
 + --cur=*) cur_="${1##--cur=}" ;;
 + --sfx=*) sfx="${1##--sfx=}" ;;
 + *) return 1 ;;
 + esac
 + shift
 + done
 +
 + if test -r "$tags"; then
 + __gitcomp_direct "$(__git_match_ctag "$cur_" "$tags" "$pfx" "$sfx")"
 + fi
 +}
 +
 +_git_grep ()
 +{
 + __git_has_doubledash && return
 +
 + case "$cur" in
 + --*)
 + __gitcomp_builtin grep
 + return
 + ;;
 + esac
 +
 + case "$cword,$prev" in
 + $((__git_cmd_idx+1)),*|*,-*)
 + __git_complete_symbol && return
 + ;;
 + esac
 +
 + __git_complete_refs
 +}
 +
 +_git_help ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin help
 + return
 + ;;
 + esac
 + if test -n "${GIT_TESTING_ALL_COMMAND_LIST-}"
 + then
 + __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(__git --list-cmds=alias,list-guide) gitk"
 + else
 + __gitcomp "$(__git --list-cmds=main,nohelpers,alias,list-guide) gitk"
 + fi
 +}
 +
 +_git_init ()
 +{
 + case "$cur" in
 + --shared=*)
 + __gitcomp "
 + false true umask group all world everybody
 + " "" "${cur##--shared=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin init
 + return
 + ;;
 + esac
 +}
 +
 +_git_ls_files ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin ls-files
 + return
 + ;;
 + esac
 +
 + # XXX ignore options like --modified and always suggest all cached
 + # files.
 + __git_complete_index_file "--cached"
 +}
 +
 +_git_ls_remote ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin ls-remote
 + return
 + ;;
 + esac
 + __gitcomp_nl "$(__git_remotes)"
 +}
 +
 +_git_ls_tree ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin ls-tree
 + return
 + ;;
 + esac
 +
 + __git_complete_file
 +}
 +
 +# Options that go well for log, shortlog and gitk
 +__git_log_common_options="
 + --not --all
 + --branches --tags --remotes
 + --first-parent --merges --no-merges
 + --max-count=
 + --max-age= --since= --after=
 + --min-age= --until= --before=
 + --min-parents= --max-parents=
 + --no-min-parents --no-max-parents
 + --alternate-refs --ancestry-path
 + --author-date-order --basic-regexp
 + --bisect --boundary --exclude-first-parent-only
 + --exclude-hidden --extended-regexp
 + --fixed-strings --grep-reflog
 + --ignore-missing --left-only --perl-regexp
 + --reflog --regexp-ignore-case --remove-empty
 + --right-only --show-linear-break
 + --show-notes-by-default --show-pulls
 + --since-as-filter --single-worktree
 +"
 +# Options that go well for log and gitk (not shortlog)
 +__git_log_gitk_options="
 + --dense --sparse --full-history
 + --simplify-merges --simplify-by-decoration
 + --left-right --notes --no-notes
 +"
 +# Options that go well for log and shortlog (not gitk)
 +__git_log_shortlog_options="
 + --author= --committer= --grep=
 + --all-match --invert-grep
 +"
 +# Options accepted by log and show
 +__git_log_show_options="
 + --diff-merges --diff-merges= --no-diff-merges --dd --remerge-diff
 + --encoding=
 +"
 +
 +__git_diff_merges_opts="off none on first-parent 1 separate m combined c dense-combined cc remerge r"
 +
 +__git_log_pretty_formats="oneline short medium full fuller reference email raw format: tformat: mboxrd"
 +__git_log_date_formats="relative iso8601 iso8601-strict rfc2822 short local default human raw unix auto: format:"
 +
 +_git_log ()
 +{
 + __git_has_doubledash && return
 + __git_find_repo_path
 +
 + local merge=""
 + if __git_pseudoref_exists MERGE_HEAD; then
 + merge="--merge"
 + fi
 + case "$prev,$cur" in
 + -L,:*:*)
 + return # fall back to Bash filename completion
 + ;;
 + -L,:*)
 + __git_complete_symbol --cur="${cur#:}" --sfx=":"
 + return
 + ;;
 + -G,*|-S,*)
 + __git_complete_symbol
 + return
 + ;;
 + esac
 + case "$cur" in
 + --pretty=*|--format=*)
 + __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
 + " "" "${cur#*=}"
 + return
 + ;;
 + --date=*)
 + __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
 + return
 + ;;
 + --decorate=*)
 + __gitcomp "full short no" "" "${cur##--decorate=}"
 + return
 + ;;
 + --diff-algorithm=*)
 + __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
 + return
 + ;;
 + --submodule=*)
 + __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
 + return
 + ;;
 + --ws-error-highlight=*)
 + __gitcomp "$__git_ws_error_highlight_opts" "" "${cur##--ws-error-highlight=}"
 + return
 + ;;
 + --no-walk=*)
 + __gitcomp "sorted unsorted" "" "${cur##--no-walk=}"
 + return
 + ;;
 + --diff-merges=*)
 +                __gitcomp "$__git_diff_merges_opts" "" "${cur##--diff-merges=}"
 +                return
 +                ;;
 + --*)
 + __gitcomp "
 + $__git_log_common_options
 + $__git_log_shortlog_options
 + $__git_log_gitk_options
 + $__git_log_show_options
 + --root --topo-order --date-order --reverse
 + --follow --full-diff
 + --abbrev-commit --no-abbrev-commit --abbrev=
 + --relative-date --date=
 + --pretty= --format= --oneline
 + --show-signature
 + --cherry-mark
 + --cherry-pick
 + --graph
 + --decorate --decorate= --no-decorate
 + --walk-reflogs
 + --no-walk --no-walk= --do-walk
 + --parents --children
 + --expand-tabs --expand-tabs= --no-expand-tabs
 + --clear-decorations --decorate-refs=
 + --decorate-refs-exclude=
 + $merge
 + $__git_diff_common_options
 + "
 + return
 + ;;
 + -L:*:*)
 + return # fall back to Bash filename completion
 + ;;
 + -L:*)
 + __git_complete_symbol --cur="${cur#-L:}" --sfx=":"
 + return
 + ;;
 + -G*)
 + __git_complete_symbol --pfx="-G" --cur="${cur#-G}"
 + return
 + ;;
 + -S*)
 + __git_complete_symbol --pfx="-S" --cur="${cur#-S}"
 + return
 + ;;
 + esac
 + __git_complete_revlist
 +}
 +
 +_git_merge ()
 +{
 + __git_complete_strategy && return
 +
 + case "$cur" in
 + --*)
 + __gitcomp_builtin merge
 + return
 + esac
 + __git_complete_refs
 +}
 +
 +_git_mergetool ()
 +{
 + case "$cur" in
 + --tool=*)
 + __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
 + return
 + ;;
 + --*)
 + __gitcomp "--tool= --prompt --no-prompt --gui --no-gui"
 + return
 + ;;
 + esac
 +}
 +
 +_git_merge_base ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin merge-base
 + return
 + ;;
 + esac
 + __git_complete_refs
 +}
 +
 +_git_mv ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin mv
 + return
 + ;;
 + esac
 +
 + if [ $(__git_count_arguments "mv") -gt 0 ]; then
 + # We need to show both cached and untracked files (including
 + # empty directories) since this may not be the last argument.
 + __git_complete_index_file "--cached --others --directory"
 + else
 + __git_complete_index_file "--cached"
 + fi
 +}
 +
 +_git_notes ()
 +{
 + local subcommands='add append copy edit get-ref list merge prune remove show'
 + local subcommand="$(__git_find_on_cmdline "$subcommands")"
 +
 + case "$subcommand,$cur" in
 + ,--*)
 + __gitcomp_builtin notes
 + ;;
 + ,*)
 + case "$prev" in
 + --ref)
 + __git_complete_refs
 + ;;
 + *)
 + __gitcomp "$subcommands --ref"
 + ;;
 + esac
 + ;;
 + *,--reuse-message=*|*,--reedit-message=*)
 + __git_complete_refs --cur="${cur#*=}"
 + ;;
 + *,--*)
 + __gitcomp_builtin notes_$subcommand
 + ;;
 + prune,*|get-ref,*)
 + # this command does not take a ref, do not complete it
 + ;;
 + *)
 + case "$prev" in
 + -m|-F)
 + ;;
 + *)
 + __git_complete_refs
 + ;;
 + esac
 + ;;
 + esac
 +}
 +
 +_git_pull ()
 +{
 + __git_complete_strategy && return
 +
 + case "$cur" in
 + --recurse-submodules=*)
 + __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin pull
 +
 + return
 + ;;
 + esac
 + __git_complete_remote_or_refspec
 +}
 +
 +__git_push_recurse_submodules="check on-demand only"
 +
 +__git_complete_force_with_lease ()
 +{
 + local cur_=$1
 +
 + case "$cur_" in
 + --*=)
 + ;;
 + *:*)
 + __git_complete_refs --cur="${cur_#*:}"
 + ;;
 + *)
 + __git_complete_refs --cur="$cur_"
 + ;;
 + esac
 +}
 +
 +_git_push ()
 +{
 + case "$prev" in
 + --repo)
 + __gitcomp_nl "$(__git_remotes)"
 + return
 + ;;
 + --recurse-submodules)
 + __gitcomp "$__git_push_recurse_submodules"
 + return
 + ;;
 + esac
 + case "$cur" in
 + --repo=*)
 + __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
 + return
 + ;;
 + --recurse-submodules=*)
 + __gitcomp "$__git_push_recurse_submodules" "" "${cur##--recurse-submodules=}"
 + return
 + ;;
 + --force-with-lease=*)
 + __git_complete_force_with_lease "${cur##--force-with-lease=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin push
 + return
 + ;;
 + esac
 + __git_complete_remote_or_refspec
 +}
 +
 +_git_range_diff ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp "
 + --creation-factor= --no-dual-color
 + $__git_diff_common_options
 + "
 + return
 + ;;
 + esac
 + __git_complete_revlist
 +}
 +
 +__git_rebase_inprogress_options="--continue --skip --abort --quit --show-current-patch"
 +__git_rebase_interactive_inprogress_options="$__git_rebase_inprogress_options --edit-todo"
 +
 +_git_rebase ()
 +{
 + __git_find_repo_path
 + if [ -f "$__git_repo_path"/rebase-merge/interactive ]; then
 + __gitcomp "$__git_rebase_interactive_inprogress_options"
 + return
 + elif [ -d "$__git_repo_path"/rebase-apply ] || \
 +      [ -d "$__git_repo_path"/rebase-merge ]; then
 + __gitcomp "$__git_rebase_inprogress_options"
 + return
 + fi
 + __git_complete_strategy && return
 + case "$cur" in
 + --whitespace=*)
 + __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 + return
 + ;;
 + --onto=*)
 + __git_complete_refs --cur="${cur##--onto=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin rebase "" \
 + "$__git_rebase_interactive_inprogress_options"
 +
 + return
 + esac
 + __git_complete_refs
 +}
 +
 +_git_reflog ()
 +{
 + local subcommands="show delete expire"
 + local subcommand="$(__git_find_on_cmdline "$subcommands")"
 +
 + if [ -z "$subcommand" ]; then
 + __gitcomp "$subcommands"
 + else
 + __git_complete_refs
 + fi
 +}
 +
 +__git_send_email_confirm_options="always never auto cc compose"
 +__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
 +
 +_git_send_email ()
 +{
 + case "$prev" in
 + --to|--cc|--bcc|--from)
 + __gitcomp "$(__git send-email --dump-aliases)"
 + return
 + ;;
 + esac
 +
 + case "$cur" in
 + --confirm=*)
 + __gitcomp "
 + $__git_send_email_confirm_options
 + " "" "${cur##--confirm=}"
 + return
 + ;;
 + --suppress-cc=*)
 + __gitcomp "
 + $__git_send_email_suppresscc_options
 + " "" "${cur##--suppress-cc=}"
 +
 + return
 + ;;
 + --smtp-encryption=*)
 + __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
 + return
 + ;;
 + --thread=*)
 + __gitcomp "
 + deep shallow
 + " "" "${cur##--thread=}"
 + return
 + ;;
 + --to=*|--cc=*|--bcc=*|--from=*)
 + __gitcomp "$(__git send-email --dump-aliases)" "" "${cur#--*=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin send-email "$__git_format_patch_extra_options"
 + return
 + ;;
 + esac
 + __git_complete_revlist
 +}
 +
 +_git_stage ()
 +{
 + _git_add
 +}
 +
 +_git_status ()
 +{
 + local complete_opt
 + local untracked_state
 +
 + case "$cur" in
 + --ignore-submodules=*)
 + __gitcomp "none untracked dirty all" "" "${cur##--ignore-submodules=}"
 + return
 + ;;
 + --untracked-files=*)
 + __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
 + return
 + ;;
 + --column=*)
 + __gitcomp "
 + always never auto column row plain dense nodense
 + " "" "${cur##--column=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin status
 + return
 + ;;
 + esac
 +
 + untracked_state="$(__git_get_option_value "-u" "--untracked-files=" \
 + "$__git_untracked_file_modes" "status.showUntrackedFiles")"
 +
 + case "$untracked_state" in
 + no)
 + # --ignored option does not matter
 + complete_opt=
 + ;;
 + all|normal|*)
 + complete_opt="--cached --directory --no-empty-directory --others"
 +
 + if [ -n "$(__git_find_on_cmdline "--ignored")" ]; then
 + complete_opt="$complete_opt --ignored --exclude=*"
 + fi
 + ;;
 + esac
 +
 + __git_complete_index_file "$complete_opt"
 +}
 +
 +_git_switch ()
 +{
 + local dwim_opt="$(__git_checkout_default_dwim_mode)"
 +
 + case "$prev" in
 + -c|-C|--orphan)
 + # Complete local branches (and DWIM branch
 + # remote branch names) for an option argument
 + # specifying a new branch name. This is for
 + # convenience, assuming new branches are
 + # possibly based on pre-existing branch names.
 + __git_complete_refs $dwim_opt --mode="heads"
 + return
 + ;;
 + *)
 + ;;
 + esac
 +
 + case "$cur" in
 + --conflict=*)
 + __gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
 + ;;
 + --*)
 + __gitcomp_builtin switch
 + ;;
 + *)
 + # Unlike in git checkout, git switch --orphan does not take
 + # a start point. Thus we really have nothing to complete after
 + # the branch name.
 + if [ -n "$(__git_find_on_cmdline "--orphan")" ]; then
 + return
 + fi
 +
 + # At this point, we've already handled special completion for
 + # -c/-C, and --orphan. There are 3 main things left to
 + # complete:
 + # 1) a start-point for -c/-C or -d/--detach
 + # 2) a remote head, for --track
 + # 3) a branch name, possibly including DWIM remote branches
 +
 + if [ -n "$(__git_find_on_cmdline "-c -C -d --detach")" ]; then
 + __git_complete_refs --mode="refs"
 + elif [ -n "$(__git_find_on_cmdline "-t --track")" ]; then
 + __git_complete_refs --mode="remote-heads"
 + else
 + __git_complete_refs $dwim_opt --mode="heads"
 + fi
 + ;;
 + esac
 +}
 +
 +__git_config_get_set_variables ()
 +{
 + local prevword word config_file= c=$cword
 + while [ $c -gt "$__git_cmd_idx" ]; do
 + word="${words[c]}"
 + case "$word" in
 + --system|--global|--local|--file=*)
 + config_file="$word"
 + break
 + ;;
 + -f|--file)
 + config_file="$word $prevword"
 + break
 + ;;
 + esac
 + prevword=$word
 + c=$((--c))
 + done
 +
 + __git config $config_file --name-only --list
 +}
 +
 +__git_config_vars=
 +__git_compute_config_vars ()
 +{
 + test -n "$__git_config_vars" ||
 + __git_config_vars="$(git help --config-for-completion)"
 +}
 +
 +__git_config_sections=
 +__git_compute_config_sections ()
 +{
 + test -n "$__git_config_sections" ||
 + __git_config_sections="$(git help --config-sections-for-completion)"
 +}
 +
 +# Completes possible values of various configuration variables.
 +#
 +# Usage: __git_complete_config_variable_value [<option>]...
 +# --varname=<word>: The name of the configuration variable whose value is
 +#                   to be completed.  Defaults to the previous word on the
 +#                   command line.
 +# --cur=<word>: The current value to be completed.  Defaults to the current
 +#               word to be completed.
 +__git_complete_config_variable_value ()
 +{
 + local varname="$prev" cur_="$cur"
 +
 + while test $# != 0; do
 + case "$1" in
 + --varname=*) varname="${1##--varname=}" ;;
 + --cur=*) cur_="${1##--cur=}" ;;
 + *) return 1 ;;
 + esac
 + shift
 + done
 +
 + if [ "${BASH_VERSINFO[0]:-0}" -ge 4 ]; then
 + varname="${varname,,}"
 + else
 + varname="$(echo "$varname" |tr A-Z a-z)"
 + fi
 +
 + case "$varname" in
 + branch.*.remote|branch.*.pushremote)
 + __gitcomp_nl "$(__git_remotes)" "" "$cur_"
 + return
 + ;;
 + branch.*.merge)
 + __git_complete_refs --cur="$cur_"
 + return
 + ;;
 + branch.*.rebase)
 + __gitcomp "false true merges interactive" "" "$cur_"
 + return
 + ;;
 + remote.pushdefault)
 + __gitcomp_nl "$(__git_remotes)" "" "$cur_"
 + return
 + ;;
 + remote.*.fetch)
 + local remote="${varname#remote.}"
 + remote="${remote%.fetch}"
 + if [ -z "$cur_" ]; then
 + __gitcomp_nl "refs/heads/" "" "" ""
 + return
 + fi
 + __gitcomp_nl "$(__git_refs_remotes "$remote")" "" "$cur_"
 + return
 + ;;
 + remote.*.push)
 + local remote="${varname#remote.}"
 + remote="${remote%.push}"
 + __gitcomp_nl "$(__git for-each-ref \
 + --format='%(refname):%(refname)' refs/heads)" "" "$cur_"
 + return
 + ;;
 + pull.twohead|pull.octopus)
 + __git_compute_merge_strategies
 + __gitcomp "$__git_merge_strategies" "" "$cur_"
 + return
 + ;;
 + color.pager)
 + __gitcomp "false true" "" "$cur_"
 + return
 + ;;
 + color.*.*)
 + __gitcomp "
 + normal black red green yellow blue magenta cyan white
 + bold dim ul blink reverse
 + " "" "$cur_"
 + return
 + ;;
 + color.*)
 + __gitcomp "false true always never auto" "" "$cur_"
 + return
 + ;;
 + diff.submodule)
 + __gitcomp "$__git_diff_submodule_formats" "" "$cur_"
 + return
 + ;;
 + help.format)
 + __gitcomp "man info web html" "" "$cur_"
 + return
 + ;;
 + log.date)
 + __gitcomp "$__git_log_date_formats" "" "$cur_"
 + return
 + ;;
 + sendemail.aliasfiletype)
 + __gitcomp "mutt mailrc pine elm gnus" "" "$cur_"
 + return
 + ;;
 + sendemail.confirm)
 + __gitcomp "$__git_send_email_confirm_options" "" "$cur_"
 + return
 + ;;
 + sendemail.suppresscc)
 + __gitcomp "$__git_send_email_suppresscc_options" "" "$cur_"
 + return
 + ;;
 + sendemail.transferencoding)
 + __gitcomp "7bit 8bit quoted-printable base64" "" "$cur_"
 + return
 + ;;
 + *.*)
 + return
 + ;;
 + esac
 +}
 +
 +# Completes configuration sections, subsections, variable names.
 +#
 +# Usage: __git_complete_config_variable_name [<option>]...
 +# --cur=<word>: The current configuration section/variable name to be
 +#               completed.  Defaults to the current word to be completed.
 +# --sfx=<suffix>: A suffix to be appended to each fully completed
 +#                 configuration variable name (but not to sections or
 +#                 subsections) instead of the default space.
 +__git_complete_config_variable_name ()
 +{
 + local cur_="$cur" sfx
 +
 + while test $# != 0; do
 + case "$1" in
 + --cur=*) cur_="${1##--cur=}" ;;
 + --sfx=*) sfx="${1##--sfx=}" ;;
 + *) return 1 ;;
 + esac
 + shift
 + done
 +
 + case "$cur_" in
 + branch.*.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_##*.}"
 + __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx"
 + return
 + ;;
 + branch.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_#*.}"
 + __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
 + __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "${sfx- }"
 + return
 + ;;
 + guitool.*.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_##*.}"
 + __gitcomp "
 + argPrompt cmd confirm needsFile noConsole noRescan
 + prompt revPrompt revUnmerged title
 + " "$pfx" "$cur_" "$sfx"
 + return
 + ;;
 + difftool.*.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_##*.}"
 + __gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
 + return
 + ;;
 + man.*.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_##*.}"
 + __gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
 + return
 + ;;
 + mergetool.*.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_##*.}"
 + __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx"
 + return
 + ;;
 + pager.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_#*.}"
 + __git_compute_all_commands
 + __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "${sfx- }"
 + return
 + ;;
 + remote.*.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_##*.}"
 + __gitcomp "
 + url proxy fetch push mirror skipDefaultUpdate
 + receivepack uploadpack tagOpt pushurl
 + " "$pfx" "$cur_" "$sfx"
 + return
 + ;;
 + remote.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_#*.}"
 + __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
 + __gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "${sfx- }"
 + return
 + ;;
 + url.*.*)
 + local pfx="${cur_%.*}."
 + cur_="${cur_##*.}"
 + __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx"
 + return
 + ;;
 + *.*)
 + __git_compute_config_vars
 + __gitcomp "$__git_config_vars" "" "$cur_" "$sfx"
 + ;;
 + *)
 + __git_compute_config_sections
 + __gitcomp "$__git_config_sections" "" "$cur_" "."
 + ;;
 + esac
 +}
 +
 +# Completes '='-separated configuration sections/variable names and values
 +# for 'git -c section.name=value'.
 +#
 +# Usage: __git_complete_config_variable_name_and_value [<option>]...
 +# --cur=<word>: The current configuration section/variable name/value to be
 +#               completed. Defaults to the current word to be completed.
 +__git_complete_config_variable_name_and_value ()
 +{
 + local cur_="$cur"
 +
 + while test $# != 0; do
 + case "$1" in
 + --cur=*) cur_="${1##--cur=}" ;;
 + *) return 1 ;;
 + esac
 + shift
 + done
 +
 + case "$cur_" in
 + *=*)
 + __git_complete_config_variable_value \
 + --varname="${cur_%%=*}" --cur="${cur_#*=}"
 + ;;
 + *)
 + __git_complete_config_variable_name --cur="$cur_" --sfx='='
 + ;;
 + esac
 +}
 +
 +_git_config ()
 +{
 + case "$prev" in
 + --get|--get-all|--unset|--unset-all)
 + __gitcomp_nl "$(__git_config_get_set_variables)"
 + return
 + ;;
 + *.*)
 + __git_complete_config_variable_value
 + return
 + ;;
 + esac
 + case "$cur" in
 + --*)
 + __gitcomp_builtin config
 + ;;
 + *)
 + __git_complete_config_variable_name
 + ;;
 + esac
 +}
 +
 +_git_remote ()
 +{
 + local subcommands="
 + add rename remove set-head set-branches
 + get-url set-url show prune update
 + "
 + local subcommand="$(__git_find_on_cmdline "$subcommands")"
 + if [ -z "$subcommand" ]; then
 + case "$cur" in
 + --*)
 + __gitcomp_builtin remote
 + ;;
 + *)
 + __gitcomp "$subcommands"
 + ;;
 + esac
 + return
 + fi
 +
 + case "$subcommand,$cur" in
 + add,--*)
 + __gitcomp_builtin remote_add
 + ;;
 + add,*)
 + ;;
 + set-head,--*)
 + __gitcomp_builtin remote_set-head
 + ;;
 + set-branches,--*)
 + __gitcomp_builtin remote_set-branches
 + ;;
 + set-head,*|set-branches,*)
 + __git_complete_remote_or_refspec
 + ;;
 + update,--*)
 + __gitcomp_builtin remote_update
 + ;;
 + update,*)
 + __gitcomp "$(__git_remotes) $(__git_get_config_variables "remotes")"
 + ;;
 + set-url,--*)
 + __gitcomp_builtin remote_set-url
 + ;;
 + get-url,--*)
 + __gitcomp_builtin remote_get-url
 + ;;
 + prune,--*)
 + __gitcomp_builtin remote_prune
 + ;;
 + *)
 + __gitcomp_nl "$(__git_remotes)"
 + ;;
 + esac
 +}
 +
 +_git_replace ()
 +{
 + case "$cur" in
 + --format=*)
 + __gitcomp "short medium long" "" "${cur##--format=}"
 + return
 + ;;
 + --*)
 + __gitcomp_builtin replace
 + return
 + ;;
 + esac
 + __git_complete_refs
 +}
 +
 +_git_rerere ()
 +{
 + local subcommands="clear forget diff remaining status gc"
 + local subcommand="$(__git_find_on_cmdline "$subcommands")"
 + if test -z "$subcommand"
 + then
 + __gitcomp "$subcommands"
 + return
 + fi
 +}
 +
 +_git_reset ()
 +{
 + __git_has_doubledash && return
 +
 + case "$cur" in
 + --*)
 + __gitcomp_builtin reset
 + return
 + ;;
 + esac
 + __git_complete_refs
 +}
 +
 +_git_restore ()
 +{
 + case "$prev" in
 + -s)
 + __git_complete_refs
 + return
 + ;;
 + esac
 +
 + case "$cur" in
 + --conflict=*)
 + __gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
 + ;;
 + --source=*)
 + __git_complete_refs --cur="${cur##--source=}"
 + ;;
 + --*)
 + __gitcomp_builtin restore
 + ;;
 + *)
 + if __git_pseudoref_exists HEAD; then
 + __git_complete_index_file "--modified"
 + fi
 + esac
 +}
 +
 +__git_revert_inprogress_options=$__git_sequencer_inprogress_options
 +
 +_git_revert ()
 +{
 + if __git_pseudoref_exists REVERT_HEAD; then
 + __gitcomp "$__git_revert_inprogress_options"
 + return
 + fi
 + __git_complete_strategy && return
 + case "$cur" in
 + --*)
 + __gitcomp_builtin revert "" \
 + "$__git_revert_inprogress_options"
 + return
 + ;;
 + esac
 + __git_complete_refs
 +}
 +
 +_git_rm ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin rm
 + return
 + ;;
 + esac
 +
 + __git_complete_index_file "--cached"
 +}
 +
 +_git_shortlog ()
 +{
 + __git_has_doubledash && return
 +
 + case "$cur" in
 + --*)
 + __gitcomp "
 + $__git_log_common_options
 + $__git_log_shortlog_options
 + --numbered --summary --email
 + "
 + return
 + ;;
 + esac
 + __git_complete_revlist
 +}
 +
 +_git_show ()
 +{
 + __git_has_doubledash && return
 +
 + case "$cur" in
 + --pretty=*|--format=*)
 + __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
 + " "" "${cur#*=}"
 + return
 + ;;
 + --diff-algorithm=*)
 + __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
 + return
 + ;;
 + --submodule=*)
 + __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
 + return
 + ;;
 + --color-moved=*)
 + __gitcomp "$__git_color_moved_opts" "" "${cur##--color-moved=}"
 + return
 + ;;
 + --color-moved-ws=*)
 + __gitcomp "$__git_color_moved_ws_opts" "" "${cur##--color-moved-ws=}"
 + return
 + ;;
 + --ws-error-highlight=*)
 + __gitcomp "$__git_ws_error_highlight_opts" "" "${cur##--ws-error-highlight=}"
 + return
 + ;;
 + --diff-merges=*)
 +                __gitcomp "$__git_diff_merges_opts" "" "${cur##--diff-merges=}"
 +                return
 +                ;;
 + --*)
 + __gitcomp "--pretty= --format= --abbrev-commit --no-abbrev-commit
 + --oneline --show-signature
 + --expand-tabs --expand-tabs= --no-expand-tabs
 + $__git_log_show_options
 + $__git_diff_common_options
 + "
 + return
 + ;;
 + esac
 + __git_complete_revlist_file
 +}
 +
 +_git_show_branch ()
 +{
 + case "$cur" in
 + --*)
 + __gitcomp_builtin show-branch
 + return
 + ;;
 + esac
 + __git_complete_revlist
 +}
 +
 +__gitcomp_directories ()
 +{
 + local _tmp_dir _tmp_completions _found=0
 +
 + # Get the directory of the current token; this differs from dirname
 + # in that it keeps up to the final trailing slash.  If no slash found
 + # that's fine too.
 + [[ "$cur" =~ .*/ ]]
 + _tmp_dir=$BASH_REMATCH
 +
 + # Find possible directory completions, adding trailing '/' characters,
 + # de-quoting, and handling unusual characters.
 + while IFS= read -r -d $'\0' c ; do
 + # If there are directory completions, find ones that start
 + # with "$cur", the current token, and put those in COMPREPLY
 + if [[ $c == "$cur"* ]]; then
 + COMPREPLY+=("$c/")
 + _found=1
 + fi
 + done < <(__git ls-tree -z -d --name-only HEAD $_tmp_dir)
 +
 + if [[ $_found == 0 ]] && [[ "$cur" =~ /$ ]]; then
 + # No possible further completions any deeper, so assume we're at
 + # a leaf directory and just consider it complete
 + __gitcomp_direct_append "$cur "
 + elif [[ $_found == 0 ]]; then
 + # No possible completions found.  Avoid falling back to
 + # bash's default file and directory completion, because all
 + # valid completions have already been searched and the
 + # fallbacks can do nothing but mislead.  In fact, they can
 + # mislead in three different ways:
 + #    1) Fallback file completion makes no sense when asking
 + #       for directory completions, as this function does.
 + #    2) Fallback directory completion is bad because
 + #       e.g. "/pro" is invalid and should NOT complete to
 + #       "/proc".
 + #    3) Fallback file/directory completion only completes
 + #       on paths that exist in the current working tree,
 + #       i.e. which are *already* part of their
 + #       sparse-checkout.  Thus, normal file and directory
 + #       completion is always useless for "git
 + #       sparse-checkout add" and is also probelmatic for
 + #       "git sparse-checkout set" unless using it to
 + #       strictly narrow the checkout.
 + COMPREPLY=( "" )
 + fi
 +}
 +
 +# In non-cone mode, the arguments to {set,add} are supposed to be
 +# patterns, relative to the toplevel directory.  These can be any kind
 +# of general pattern, like 'subdir/*.c' and we can't complete on all
 +# of those.  However, if the user presses Tab to get tab completion, we
 +# presume that they are trying to provide a pattern that names a specific
 +# path.
 +__gitcomp_slash_leading_paths ()
 +{
 + local dequoted_word pfx="" cur_ toplevel
 +
 + # Since we are dealing with a sparse-checkout, subdirectories may not
 + # exist in the local working copy.  Therefore, we want to run all
 + # ls-files commands relative to the repository toplevel.
 + toplevel="$(git rev-parse --show-toplevel)/"
 +
 + __git_dequote "$cur"
 +
 + # If the paths provided by the user already start with '/', then
 + # they are considered relative to the toplevel of the repository
 + # already.  If they do not start with /, then we need to adjust
 + # them to start with the appropriate prefix.
 + case "$cur" in
 + /*)
 + cur="${cur:1}"
 + ;;
 + *)
 + pfx="$(__git rev-parse --show-prefix)"
 + esac
 +
 + # Since sparse-index is limited to cone-mode, in non-cone-mode the
 + # list of valid paths is precisely the cached files in the index.
 + #
 + # NEEDSWORK:
 + #   1) We probably need to take care of cases where ls-files
 + #      responds with special quoting.
 + #   2) We probably need to take care of cases where ${cur} has
 + #      some kind of special quoting.
 + #   3) On top of any quoting from 1 & 2, we have to provide an extra
 + #      level of quoting for any paths that contain a '*', '?', '\',
 + #      '[', ']', or leading '#' or '!' since those will be
 + #      interpreted by sparse-checkout as something other than a
 + #      literal path character.
 + # Since there are two types of quoting here, this might get really
 + # complex.  For now, just punt on all of this...
 + completions="$(__git -C "${toplevel}" -c core.quotePath=false \
 + ls-files --cached -- "${pfx}${cur}*" \
 + | sed -e s%^%/% -e 's%$% %')"
 + # Note, above, though that we needed all of the completions to be
 + # prefixed with a '/', and we want to add a space so that bash
 + # completion will actually complete an entry and let us move on to
 + # the next one.
 +
 + # Return what we've found.
 + if test -n "$completions"; then
 + # We found some completions; return them
 + local IFS=$'\n'
 + COMPREPLY=($completions)
 + else
 + # Do NOT fall back to bash-style all-local-files-and-dirs
 + # when we find no match.  Such options are worse than
 + # useless:
 + #     1. "git sparse-checkout add" needs paths that are NOT
 + #        currently in the working copy.  "git
 + #        sparse-checkout set" does as well, except in the
 + #        special cases when users are only trying to narrow
 + #        their sparse checkout to a subset of what they
 + #        already have.
 + #
 + #     2. A path like '.config' is ambiguous as to whether
 + #        the user wants all '.config' files throughout the
 + #        tree, or just the one under the current directory.
 + #        It would result in a warning from the
 + #        sparse-checkout command due to this.  As such, all
 + #        completions of paths should be prefixed with a
 + #        '/'.
 + #
 + #     3. We don't want paths prefixed with a '/' to
 + #        complete files in the system root directory, we
 + #        want it to complete on files relative to the
 + #        repository root.
 + #
 + # As such, make sure that NO completions are offered rather
 + # than falling back to bash's default completions.
 + COMPREPLY=( "" )
 + fi
 +}
 +
 +_git_sparse_checkout ()
 +{
 + local subcommands="list init set disable add reapply"
 + local subcommand="$(__git_find_on_cmdline "$subcommands")"
 + local using_cone=true
 + if [ -z "$subcommand" ]; then
 + __gitcomp "$subcommands"
 + return
 + fi
 +
 + case "$subcommand,$cur" in
 + *,--*)
 + __gitcomp_builtin sparse-checkout_$subcommand "" "--"
 + ;;
 + set,*|add,*)
 + if [[ "$(__git config core.sparseCheckout)" == "true" &&
 +       "$(__git config core.sparseCheckoutCone)" == "false" &&
 +       -z "$(__git_find_on_cmdline --cone)" ]]; then
 + using_cone=false
 + fi
 + if [[ -n "$(__git_find_on_cmdline --no-cone)" ]]; then
 + using_cone=false
 + fi
 + if [[ "$using_cone" == "true" ]]; then
 + __gitcomp_directories
 + else
 + __gitcomp_slash_leading_paths
 + fi
 + esac
 +}
 +
 +_git_stash ()
 +{
 + local subcommands='push list show apply clear drop pop create branch'
 + local subcommand="$(__git_find_on_cmdline "$subcommands save")"
 +
 + if [ -z "$subcommand" ]; then
 + case "$((cword - __git_cmd_idx)),$cur" in
 + *,--*)
 + __gitcomp_builtin stash_push
 + ;;
 + 1,sa*)
 + __gitcomp "save"
 + ;;
 + 1,*)
 + __gitcomp "$subcommands"
 + ;;
 + esac
 + return
 + fi
 +
 + case "$subcommand,$cur" in
 + list,--*)
 + # NEEDSWORK: can we somehow unify this with the options in _git_log() and _git_show()
 + __gitcomp_builtin stash_list "$__git_log_common_options $__git_diff_common_options"
 + ;;
 + show,--*)
 + __gitcomp_builtin stash_show "$__git_diff_common_options"
 + ;;
 + *,--*)
 + __gitcomp_builtin "stash_$subcommand"
 + ;;
 + branch,*)
 + if [ $cword -eq $((__git_cmd_idx+2)) ]; then
 + __git_complete_refs
 + else
 + __gitcomp_nl "$(__git stash list \
 + | sed -n -e 's/:.*//p')"
 + fi
 + ;;
 + show,*|apply,*|drop,*|pop,*)
 + __gitcomp_nl "$(__git stash list \
 + | sed -n -e 's/:.*//p')"
 + ;;
 + esac
 +}
 +
 +_git_submodule ()
 +{
 + __git_has_doubledash && return
 +
 + local subcommands="add status init deinit update set-branch set-url summary foreach sync absorbgitdirs"
 + local subcommand="$(__git_find_on_cmdline "$subcommands")"
 + if [ -z "$subcommand" ]; then
 + case "$cur" in
 + --*)
 + __gitcomp "--quiet"
 + ;;
 + *)
 + __gitcomp "$subcommands"
 + ;;
 + esac
 + return
 + fi
 +
 + case "$subcommand,$cur" in
 + add,--*)
 + __gitcomp "--branch --force --name --reference --depth"
 + ;;
 + status,--*)
 + __gitcomp "--cached --recursive"
 + ;;
 + deinit,--*)
 + __gitcomp "--force --all"
 + ;;
 + update,--*)
 + __gitcomp "
 + --init --remote --no-fetch
 + --recommend-shallow --no-recommend-shallow
 + --force --rebase --merge --reference --depth --recursive --jobs
 + "
 + ;;
 + set-branch,--*)
 + __gitcomp "--default --branch"
 + ;;
 + summary,--*)
 + __gitcomp "--cached --files --summary-limit"
 + ;;
 + foreach,--*|sync,--*)
 + __gitcomp "--recursive"
 + ;;
 + *)
 + ;;
 + esac
 +}
 +
 +_git_svn ()
 +{
 + local subcommands="
 + init fetch clone rebase dcommit log find-rev
 + set-tree commit-diff info create-ignore propget
 + proplist show-ignore show-externals branch tag blame
 + migrate mkdirs reset gc
 + "
 + local subcommand="$(__git_find_on_cmdline "$subcommands")"
 + if [ -z "$subcommand" ]; then
 + __gitcomp "$subcommands"
 + else
 + local remote_opts="--username= --config-dir= --no-auth-cache"
 + local fc_opts="
 + --follow-parent --authors-file= --repack=
 + --no-metadata --use-svm-props --use-svnsync-props
 + --log-window-size= --no-checkout --quiet
 + --repack-flags --use-log-author --localtime
 + --add-author-from
 + --recursive
 + --ignore-paths= --include-paths= $remote_opts
 + "
 + local init_opts="
 + --template= --shared= --trunk= --tags=
 + --branches= --stdlayout --minimize-url
 + --no-metadata --use-svm-props --use-svnsync-props
 + --rewrite-root= --prefix= $remote_opts
 + "
 + local cmt_opts="
 + --edit --rmdir --find-copies-harder --copy-similarity=
 + "
 +
 + case "$subcommand,$cur" in
 + fetch,--*)
 + __gitcomp "--revision= --fetch-all $fc_opts"
 + ;;
 + clone,--*)
 + __gitcomp "--revision= $fc_opts $init_opts"
 + ;;
 + init,--*)
 + __gitcomp "$init_opts"
 + ;;
 + dcommit,--*)
 + __gitcomp "
 + --merge --strategy= --verbose --dry-run
 + --fetch-all --no-rebase --commit-url
 + --revision --interactive $cmt_opts $fc_opts
 + "
 + ;;
 + set-tree,--*)
 + __gitcomp "--stdin $cmt_opts $fc_opts"
 + ;;
 + create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
 + show-externals,--*|mkdirs,--*)
 + __gitcomp "--revision="
 + ;;
 + log,--*)
 + __gitcomp "
 + --limit= --revision= --verbose --incremental
 + --oneline --show-commit --non-recursive
 + --authors-file= --color
 + "
 + ;;
 + rebase,--*)
 + __gitcomp "
 + --merge --verbose --strategy= --local
 + --fetch-all --dry-run $fc_opts
 + "
 + ;;
 + commit-diff,--*)
 + __gitcomp "--message= --file= --revision= $cmt_opts"
 + ;;
 + info,--*)
 + __gitcomp "--url"
 + ;;
 + branch,--*)
 + __gitcomp "--dry-run --message --tag"
 + ;;
 + tag,--*)
 + __gitcomp "--dry-run --message"
 + ;;
 + blame,--*)
 + __gitcomp "--git-format"
 + ;;
 + migrate,--*)
 + __gitcomp "
 + --config-dir= --ignore-paths= --minimize
 + --no-auth-cache --username=
 + "
 + ;;
 + reset,--*)
 + __gitcomp "--revision= --parent"
 + ;;
 + *)
 + ;;
 + esac
 + fi
 +}
 +
 +_git_tag ()
 +{
 + local i c="$__git_cmd_idx" f=0
 + while [ $c -lt $cword ]; do
 + i="${words[c]}"
 + case "$i" in
 + -d|--delete|-v|--verify)
 + __gitcomp_direct "$(__git_tags "" "$cur" " ")"
 + return
 + ;;
 + -f)
 + f=1
 + ;;
 + esac
 + ((c++))
 + done
 +
 + case "$prev" in
 + -m|-F)
 + ;;
 + -*|tag)
 + if [ $f = 1 ]; then
 + __gitcomp_direct "$(__git_tags "" "$cur" " ")"
 + fi
 + ;;
 + *)
 + __git_complete_refs
 + ;;
 + esac
 +
 + case "$cur" in
 + --*)
 + __gitcomp_builtin tag
 + ;;
 + esac
 +}
 +
 +_git_whatchanged ()
 +{
 + _git_log
 +}
 +
 +__git_complete_worktree_paths ()
 +{
 + local IFS=$'\n'
 + # Generate completion reply from worktree list skipping the first
 + # entry: it's the path of the main worktree, which can't be moved,
 + # removed, locked, etc.
 + __gitcomp_nl "$(git worktree list --porcelain |
 + sed -n -e '2,$ s/^worktree //p')"
 +}
 +
 +_git_worktree ()
 +{
 + local subcommands="add list lock move prune remove unlock"
 + local subcommand subcommand_idx
 +
 + subcommand="$(__git_find_on_cmdline --show-idx "$subcommands")"
 + subcommand_idx="${subcommand% *}"
 + subcommand="${subcommand#* }"
 +
 + case "$subcommand,$cur" in
 + ,*)
 + __gitcomp "$subcommands"
 + ;;
 + *,--*)
 + __gitcomp_builtin worktree_$subcommand
 + ;;
 + add,*) # usage: git worktree add [<options>] <path> [<commit-ish>]
 + # Here we are not completing an --option, it's either the
 + # path or a ref.
 + case "$prev" in
 + -b|-B) # Complete refs for branch to be created/reseted.
 + __git_complete_refs
 + ;;
 + -*) # The previous word is an -o|--option without an
 + # unstuck argument: have to complete the path for
 + # the new worktree, so don't list anything, but let
 + # Bash fall back to filename completion.
 + ;;
 + *) # The previous word is not an --option, so it must
 + # be either the 'add' subcommand, the unstuck
 + # argument of an option (e.g. branch for -b|-B), or
 + # the path for the new worktree.
 + if [ $cword -eq $((subcommand_idx+1)) ]; then
 + # Right after the 'add' subcommand: have to
 + # complete the path, so fall back to Bash
 + # filename completion.
 + :
 + else
 + case "${words[cword-2]}" in
 + -b|-B) # After '-b <branch>': have to
 + # complete the path, so fall back
 + # to Bash filename completion.
 + ;;
 + *) # After the path: have to complete
 + # the ref to be checked out.
 + __git_complete_refs
 + ;;
 + esac
 + fi
 + ;;
 + esac
 + ;;
 + lock,*|remove,*|unlock,*)
 + __git_complete_worktree_paths
 + ;;
 + move,*)
 + if [ $cword -eq $((subcommand_idx+1)) ]; then
 + # The first parameter must be an existing working
 + # tree to be moved.
 + __git_complete_worktree_paths
 + else
 + # The second parameter is the destination: it could
 + # be any path, so don't list anything, but let Bash
 + # fall back to filename completion.
 + :
 + fi
 + ;;
 + esac
 +}
 +
 +__git_complete_common () {
 + local command="$1"
 +
 + case "$cur" in
 + --*)
 + __gitcomp_builtin "$command"
 + ;;
 + esac
 +}
 +
 +__git_cmds_with_parseopt_helper=
 +__git_support_parseopt_helper () {
 + test -n "$__git_cmds_with_parseopt_helper" ||
 + __git_cmds_with_parseopt_helper="$(__git --list-cmds=parseopt)"
 +
 + case " $__git_cmds_with_parseopt_helper " in
 + *" $1 "*)
 + return 0
 + ;;
 + *)
 + return 1
 + ;;
 + esac
 +}
 +
 +__git_have_func () {
 + declare -f -- "$1" >/dev/null 2>&1
 +}
 +
 +__git_complete_command () {
 + local command="$1"
 + local completion_func="_git_${command//-/_}"
 + if ! __git_have_func $completion_func &&
 + __git_have_func _completion_loader
 + then
 + _completion_loader "git-$command"
 + fi
 + if __git_have_func $completion_func
 + then
 + $completion_func
 + return 0
 + elif __git_support_parseopt_helper "$command"
 + then
 + __git_complete_common "$command"
 + return 0
 + else
 + return 1
 + fi
 +}
 +
 +__git_main ()
 +{
 + local i c=1 command __git_dir __git_repo_path
 + local __git_C_args C_args_count=0
 + local __git_cmd_idx
 +
 + while [ $c -lt $cword ]; do
 + i="${words[c]}"
 + case "$i" in
 + --git-dir=*)
 + __git_dir="${i#--git-dir=}"
 + ;;
 + --git-dir)
 + ((c++))
 + __git_dir="${words[c]}"
 + ;;
 + --bare)
 + __git_dir="."
 + ;;
 + --help)
 + command="help"
 + break
 + ;;
 + -c|--work-tree|--namespace)
 + ((c++))
 + ;;
 + -C)
 + __git_C_args[C_args_count++]=-C
 + ((c++))
 + __git_C_args[C_args_count++]="${words[c]}"
 + ;;
 + -*)
 + ;;
 + *)
 + command="$i"
 + __git_cmd_idx="$c"
 + break
 + ;;
 + esac
 + ((c++))
 + done
 +
 + if [ -z "${command-}" ]; then
 + case "$prev" in
 + --git-dir|-C|--work-tree)
 + # these need a path argument, let's fall back to
 + # Bash filename completion
 + return
 + ;;
 + -c)
 + __git_complete_config_variable_name_and_value
 + return
 + ;;
 + --namespace)
 + # we don't support completing these options' arguments
 + return
 + ;;
 + esac
 + case "$cur" in
 + --*)
 + __gitcomp "
 + --paginate
 + --no-pager
 + --git-dir=
 + --bare
 + --version
 + --exec-path
 + --exec-path=
 + --html-path
 + --man-path
 + --info-path
 + --work-tree=
 + --namespace=
 + --no-replace-objects
 + --help
 + "
 + ;;
 + *)
 + if test -n "${GIT_TESTING_PORCELAIN_COMMAND_LIST-}"
 + then
 + __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
 + else
 + local list_cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config
 +
 + if test "${GIT_COMPLETION_SHOW_ALL_COMMANDS-}" = "1"
 + then
 + list_cmds=builtins,$list_cmds
 + fi
 + __gitcomp "$(__git --list-cmds=$list_cmds)"
 + fi
 + ;;
 + esac
 + return
 + fi
 +
 + __git_complete_command "$command" && return
 +
 + local expansion=$(__git_aliased_command "$command")
 + if [ -n "$expansion" ]; then
 + words[1]=$expansion
 + __git_complete_command "$expansion"
 + fi
 +}
 +
 +__gitk_main ()
 +{
 + __git_has_doubledash && return
 +
 + local __git_repo_path
 + __git_find_repo_path
 +
 + local merge=""
 + if __git_pseudoref_exists MERGE_HEAD; then
 + merge="--merge"
 + fi
 + case "$cur" in
 + --*)
 + __gitcomp "
 + $__git_log_common_options
 + $__git_log_gitk_options
 + $merge
 + "
 + return
 + ;;
 + esac
 + __git_complete_revlist
 +}
 +
 +if [[ -n ${ZSH_VERSION-} && -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then
 + echo "ERROR: this script is obsolete, please see git-completion.zsh" 1>&2
 + return
 +fi
 +
 +__git_func_wrap ()
 +{
 + local cur words cword prev
 + local __git_cmd_idx=0
 + _get_comp_words_by_ref -n =: cur words cword prev
 + $1
 +}
 +
 +___git_complete ()
 +{
 + local wrapper="__git_wrap${2}"
 + eval "$wrapper () { __git_func_wrap $2 ; }"
 + complete -o bashdefault -o default -o nospace -F $wrapper $1 2>/dev/null \
 + || complete -o default -o nospace -F $wrapper $1
 +}
 +
 +# Setup the completion for git commands
 +# 1: command or alias
 +# 2: function to call (e.g. `git`, `gitk`, `git_fetch`)
 +__git_complete ()
 +{
 + local func
 +
 + if __git_have_func $2; then
 + func=$2
 + elif __git_have_func __$2_main; then
 + func=__$2_main
 + elif __git_have_func _$2; then
 + func=_$2
 + else
 + echo "ERROR: could not find function '$2'" 1>&2
 + return 1
 + fi
 + ___git_complete $1 $func
 +}
 +
 +___git_complete git __git_main
 +___git_complete gitk __gitk_main
 +
 +# The following are necessary only for Cygwin, and only are needed
 +# when the user has tab-completed the executable name and consequently
 +# included the '.exe' suffix.
 +#
 +if [ "$OSTYPE" = cygwin ]; then
 + ___git_complete git.exe __git_main
 +fi
 +</code>
 +
 +==== git-prompt.sh ====
 +<code bash git-prompt.sh>
 +# bash/zsh git prompt support
 +#
 +# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
 +# Distributed under the GNU General Public License, version 2.0.
 +#
 +# This script allows you to see repository status in your prompt.
 +#
 +# To enable:
 +#
 +#    1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
 +#    2) Add the following line to your .bashrc/.zshrc:
 +#        source ~/.git-prompt.sh
 +#    3a) Change your PS1 to call __git_ps1 as
 +#        command-substitution:
 +#        Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
 +#        ZSH:  setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
 +#        the optional argument will be used as format string.
 +#    3b) Alternatively, for a slightly faster prompt, __git_ps1 can
 +#        be used for PROMPT_COMMAND in Bash or for precmd() in Zsh
 +#        with two parameters, <pre> and <post>, which are strings
 +#        you would put in $PS1 before and after the status string
 +#        generated by the git-prompt machinery.  e.g.
 +#        Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
 +#          will show username, at-sign, host, colon, cwd, then
 +#          various status string, followed by dollar and SP, as
 +#          your prompt.
 +#        ZSH:  precmd () { __git_ps1 "%n" ":%~$ " "|%s" }
 +#          will show username, pipe, then various status string,
 +#          followed by colon, cwd, dollar and SP, as your prompt.
 +#        Optionally, you can supply a third argument with a printf
 +#        format string to finetune the output of the branch status
 +#
 +# The repository status will be displayed only if you are currently in a
 +# git repository. The %s token is the placeholder for the shown status.
 +#
 +# The prompt status always includes the current branch name.
 +#
 +# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty value,
 +# unstaged (*) and staged (+) changes will be shown next to the branch
 +# name.  You can configure this per-repository with the
 +# bash.showDirtyState variable, which defaults to true once
 +# GIT_PS1_SHOWDIRTYSTATE is enabled.
 +#
 +# You can also see if currently something is stashed, by setting
 +# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
 +# then a '$' will be shown next to the branch name.
 +#
 +# If you would like to see if there're untracked files, then you can set
 +# GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked
 +# files, then a '%' will be shown next to the branch name.  You can
 +# configure this per-repository with the bash.showUntrackedFiles
 +# variable, which defaults to true once GIT_PS1_SHOWUNTRACKEDFILES is
 +# enabled.
 +#
 +# If you would like to see the difference between HEAD and its upstream,
 +# set GIT_PS1_SHOWUPSTREAM="auto" A "<" indicates you are behind, ">"
 +# indicates you are ahead, "<>" indicates you have diverged and "="
 +# indicates that there is no difference. You can further control
 +# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated list
 +# of values:
 +#
 +#     verbose       show number of commits ahead/behind (+/-) upstream
 +#     name          if verbose, then also show the upstream abbrev name
 +#     legacy        don't use the '--count' option available in recent
 +#                   versions of git-rev-list
 +#     git           always compare HEAD to @{upstream}
 +#     svn           always compare HEAD to your SVN upstream
 +#
 +# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
 +# find one, or @{upstream} otherwise.  Once you have set
 +# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
 +# setting the bash.showUpstream config variable.
 +#
 +# You can change the separator between the branch name and the above
 +# state symbols by setting GIT_PS1_STATESEPARATOR. The default separator
 +# is SP.
 +#
 +# When there is an in-progress operation such as a merge, rebase,
 +# revert, cherry-pick, or bisect, the prompt will include information
 +# related to the operation, often in the form "|<OPERATION-NAME>".
 +#
 +# When the repository has a sparse-checkout, a notification of the form
 +# "|SPARSE" will be included in the prompt.  This can be shortened to a
 +# single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted
 +# by setting GIT_PS1_OMITSPARSESTATE.
 +#
 +# If you would like to see a notification on the prompt when there are
 +# unresolved conflicts, set GIT_PS1_SHOWCONFLICTSTATE to "yes". The
 +# prompt will include "|CONFLICT".
 +#
 +# If you would like to see more information about the identity of
 +# commits checked out as a detached HEAD, set GIT_PS1_DESCRIBE_STYLE
 +# to one of these values:
 +#
 +#     contains      relative to newer annotated tag (v1.6.3.2~35)
 +#     branch        relative to newer tag or branch (master~4)
 +#     describe      relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
 +#     tag           relative to any older tag (v1.6.3.1-13-gdd42c2f)
 +#     default       exactly matching tag
 +#
 +# If you would like a colored hint about the current dirty state, set
 +# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
 +# the colored output of "git status -sb".
 +#
 +# If you would like __git_ps1 to do nothing in the case when the current
 +# directory is set up to be ignored by git, then set
 +# GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the
 +# repository level by setting bash.hideIfPwdIgnored to "false".
 +
 +# check whether printf supports -v
 +__git_printf_supports_v=
 +printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1
 +
 +# stores the divergence from upstream in $p
 +# used by GIT_PS1_SHOWUPSTREAM
 +__git_ps1_show_upstream ()
 +{
 + local key value
 + local svn_remote svn_url_pattern count n
 + local upstream_type=git legacy="" verbose="" name=""
 +
 + svn_remote=()
 + # get some config options from git-config
 + local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
 + while read -r key value; do
 + case "$key" in
 + bash.showupstream)
 + GIT_PS1_SHOWUPSTREAM="$value"
 + if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
 + p=""
 + return
 + fi
 + ;;
 + svn-remote.*.url)
 + svn_remote[$((${#svn_remote[@]} + 1))]="$value"
 + svn_url_pattern="$svn_url_pattern\\|$value"
 + upstream_type=svn+git # default upstream type is SVN if available, else git
 + ;;
 + esac
 + done <<< "$output"
 +
 + # parse configuration values
 + local option
 + for option in ${GIT_PS1_SHOWUPSTREAM}; do
 + case "$option" in
 + git|svn) upstream_type="$option" ;;
 + verbose) verbose=1 ;;
 + legacy)  legacy=1  ;;
 + name)    name=1 ;;
 + esac
 + done
 +
 + # Find our upstream type
 + case "$upstream_type" in
 + git)    upstream_type="@{upstream}" ;;
 + svn*)
 + # get the upstream from the "git-svn-id: ..." in a commit message
 + # (git-svn uses essentially the same procedure internally)
 + local -a svn_upstream
 + svn_upstream=($(git log --first-parent -1 \
 + --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
 + if [[ 0 -ne ${#svn_upstream[@]} ]]; then
 + svn_upstream=${svn_upstream[${#svn_upstream[@]} - 2]}
 + svn_upstream=${svn_upstream%@*}
 + local n_stop="${#svn_remote[@]}"
 + for ((n=1; n <= n_stop; n++)); do
 + svn_upstream=${svn_upstream#${svn_remote[$n]}}
 + done
 +
 + if [[ -z "$svn_upstream" ]]; then
 + # default branch name for checkouts with no layout:
 + upstream_type=${GIT_SVN_ID:-git-svn}
 + else
 + upstream_type=${svn_upstream#/}
 + fi
 + elif [[ "svn+git" = "$upstream_type" ]]; then
 + upstream_type="@{upstream}"
 + fi
 + ;;
 + esac
 +
 + # Find how many commits we are ahead/behind our upstream
 + if [[ -z "$legacy" ]]; then
 + count="$(git rev-list --count --left-right \
 + "$upstream_type"...HEAD 2>/dev/null)"
 + else
 + # produce equivalent output to --count for older versions of git
 + local commits
 + if commits="$(git rev-list --left-right "$upstream_type"...HEAD 2>/dev/null)"
 + then
 + local commit behind=0 ahead=0
 + for commit in $commits
 + do
 + case "$commit" in
 + "<"*) ((behind++)) ;;
 + *)    ((ahead++))  ;;
 + esac
 + done
 + count="$behind $ahead"
 + else
 + count=""
 + fi
 + fi
 +
 + # calculate the result
 + if [[ -z "$verbose" ]]; then
 + case "$count" in
 + "") # no upstream
 + p="" ;;
 + "0 0") # equal to upstream
 + p="=" ;;
 + "0 "*) # ahead of upstream
 + p=">" ;;
 + *" 0") # behind upstream
 + p="<" ;;
 + *)     # diverged from upstream
 + p="<>" ;;
 + esac
 + else # verbose, set upstream instead of p
 + case "$count" in
 + "") # no upstream
 + upstream="" ;;
 + "0 0") # equal to upstream
 + upstream="|u=" ;;
 + "0 "*) # ahead of upstream
 + upstream="|u+${count#0 }" ;;
 + *" 0") # behind upstream
 + upstream="|u-${count% 0}" ;;
 + *)     # diverged from upstream
 + upstream="|u+${count#* }-${count% *}" ;;
 + esac
 + if [[ -n "$count" && -n "$name" ]]; then
 + __git_ps1_upstream_name=$(git rev-parse \
 + --abbrev-ref "$upstream_type" 2>/dev/null)
 + if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
 + upstream="$upstream \${__git_ps1_upstream_name}"
 + else
 + upstream="$upstream ${__git_ps1_upstream_name}"
 + # not needed anymore; keep user's
 + # environment clean
 + unset __git_ps1_upstream_name
 + fi
 + fi
 + fi
 +
 +}
 +
 +# Helper function that is meant to be called from __git_ps1.  It
 +# injects color codes into the appropriate gitstring variables used
 +# to build a gitstring. Colored variables are responsible for clearing
 +# their own color.
 +__git_ps1_colorize_gitstring ()
 +{
 + if [[ -n ${ZSH_VERSION-} ]]; then
 + local c_red='%F{red}'
 + local c_green='%F{green}'
 + local c_lblue='%F{blue}'
 + local c_clear='%f'
 + else
 + # Using \001 and \002 around colors is necessary to prevent
 + # issues with command line editing/browsing/completion!
 + local c_red=$'\001\e[31m\002'
 + local c_green=$'\001\e[32m\002'
 + local c_lblue=$'\001\e[1;34m\002'
 + local c_clear=$'\001\e[0m\002'
 + fi
 + local bad_color=$c_red
 + local ok_color=$c_green
 + local flags_color="$c_lblue"
 +
 + local branch_color=""
 + if [ $detached = no ]; then
 + branch_color="$ok_color"
 + else
 + branch_color="$bad_color"
 + fi
 + if [ -n "$c" ]; then
 + c="$branch_color$c$c_clear"
 + fi
 + b="$branch_color$b$c_clear"
 +
 + if [ -n "$w" ]; then
 + w="$bad_color$w$c_clear"
 + fi
 + if [ -n "$i" ]; then
 + i="$ok_color$i$c_clear"
 + fi
 + if [ -n "$s" ]; then
 + s="$flags_color$s$c_clear"
 + fi
 + if [ -n "$u" ]; then
 + u="$bad_color$u$c_clear"
 + fi
 +}
 +
 +# Helper function to read the first line of a file into a variable.
 +# __git_eread requires 2 arguments, the file path and the name of the
 +# variable, in that order.
 +__git_eread ()
 +{
 + test -r "$1" && IFS=$'\r\n' read -r "$2" <"$1"
 +}
 +
 +# see if a cherry-pick or revert is in progress, if the user has committed a
 +# conflict resolution with 'git commit' in the middle of a sequence of picks or
 +# reverts then CHERRY_PICK_HEAD/REVERT_HEAD will not exist so we have to read
 +# the todo file.
 +__git_sequencer_status ()
 +{
 + local todo
 + if test -f "$g/CHERRY_PICK_HEAD"
 + then
 + r="|CHERRY-PICKING"
 + return 0;
 + elif test -f "$g/REVERT_HEAD"
 + then
 + r="|REVERTING"
 + return 0;
 + elif __git_eread "$g/sequencer/todo" todo
 + then
 + case "$todo" in
 + p[\ \ ]|pick[\ \ ]*)
 + r="|CHERRY-PICKING"
 + return 0
 + ;;
 + revert[\ \ ]*)
 + r="|REVERTING"
 + return 0
 + ;;
 + esac
 + fi
 + return 1
 +}
 +
 +# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
 +# when called from PS1 using command substitution
 +# in this mode it prints text to add to bash PS1 prompt (includes branch name)
 +#
 +# __git_ps1 requires 2 or 3 arguments when called from PROMPT_COMMAND (pc)
 +# in that case it _sets_ PS1. The arguments are parts of a PS1 string.
 +# when two arguments are given, the first is prepended and the second appended
 +# to the state string when assigned to PS1.
 +# The optional third parameter will be used as printf format string to further
 +# customize the output of the git-status string.
 +# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
 +__git_ps1 ()
 +{
 + # preserve exit status
 + local exit=$?
 + local pcmode=no
 + local detached=no
 + local ps1pc_start='\u@\h:\w '
 + local ps1pc_end='\$ '
 + local printf_format=' (%s)'
 +
 + case "$#" in
 + 2|3) pcmode=yes
 + ps1pc_start="$1"
 + ps1pc_end="$2"
 + printf_format="${3:-$printf_format}"
 + # set PS1 to a plain prompt so that we can
 + # simply return early if the prompt should not
 + # be decorated
 + PS1="$ps1pc_start$ps1pc_end"
 + ;;
 + 0|1) printf_format="${1:-$printf_format}"
 + ;;
 + *) return $exit
 + ;;
 + esac
 +
 + # ps1_expanded:  This variable is set to 'yes' if the shell
 + # subjects the value of PS1 to parameter expansion:
 + #
 + #   * bash does unless the promptvars option is disabled
 + #   * zsh does not unless the PROMPT_SUBST option is set
 + #   * POSIX shells always do
 + #
 + # If the shell would expand the contents of PS1 when drawing
 + # the prompt, a raw ref name must not be included in PS1.
 + # This protects the user from arbitrary code execution via
 + # specially crafted ref names.  For example, a ref named
 + # 'refs/heads/$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' might cause the
 + # shell to execute 'sudo rm -rf /' when the prompt is drawn.
 + #
 + # Instead, the ref name should be placed in a separate global
 + # variable (in the __git_ps1_* namespace to avoid colliding
 + # with the user's environment) and that variable should be
 + # referenced from PS1.  For example:
 + #
 + #     __git_ps1_foo=$(do_something_to_get_ref_name)
 + #     PS1="...stuff...\${__git_ps1_foo}...stuff..."
 + #
 + # If the shell does not expand the contents of PS1, the raw
 + # ref name must be included in PS1.
 + #
 + # The value of this variable is only relevant when in pcmode.
 + #
 + # Assume that the shell follows the POSIX specification and
 + # expands PS1 unless determined otherwise.  (This is more
 + # likely to be correct if the user has a non-bash, non-zsh
 + # shell and safer than the alternative if the assumption is
 + # incorrect.)
 + #
 + local ps1_expanded=yes
 + [ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
 + [ -z "${BASH_VERSION-}" ] || shopt -q promptvars || ps1_expanded=no
 +
 + local repo_info rev_parse_exit_code
 + repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
 + --is-bare-repository --is-inside-work-tree --show-ref-format \
 + --short HEAD 2>/dev/null)"
 + rev_parse_exit_code="$?"
 +
 + if [ -z "$repo_info" ]; then
 + return $exit
 + fi
 +
 + local short_sha=""
 + if [ "$rev_parse_exit_code" = "0" ]; then
 + short_sha="${repo_info##*$'\n'}"
 + repo_info="${repo_info%$'\n'*}"
 + fi
 + local ref_format="${repo_info##*$'\n'}"
 + repo_info="${repo_info%$'\n'*}"
 + local inside_worktree="${repo_info##*$'\n'}"
 + repo_info="${repo_info%$'\n'*}"
 + local bare_repo="${repo_info##*$'\n'}"
 + repo_info="${repo_info%$'\n'*}"
 + local inside_gitdir="${repo_info##*$'\n'}"
 + local g="${repo_info%$'\n'*}"
 +
 + if [ "true" = "$inside_worktree" ] &&
 +    [ -n "${GIT_PS1_HIDE_IF_PWD_IGNORED-}" ] &&
 +    [ "$(git config --bool bash.hideIfPwdIgnored)" != "false" ] &&
 +    git check-ignore -q .
 + then
 + return $exit
 + fi
 +
 + local sparse=""
 + if [ -z "${GIT_PS1_COMPRESSSPARSESTATE-}" ] &&
 +    [ -z "${GIT_PS1_OMITSPARSESTATE-}" ] &&
 +    [ "$(git config --bool core.sparseCheckout)" = "true" ]; then
 + sparse="|SPARSE"
 + fi
 +
 + local r=""
 + local b=""
 + local step=""
 + local total=""
 + if [ -d "$g/rebase-merge" ]; then
 + __git_eread "$g/rebase-merge/head-name" b
 + __git_eread "$g/rebase-merge/msgnum" step
 + __git_eread "$g/rebase-merge/end" total
 + r="|REBASE"
 + else
 + if [ -d "$g/rebase-apply" ]; then
 + __git_eread "$g/rebase-apply/next" step
 + __git_eread "$g/rebase-apply/last" total
 + if [ -f "$g/rebase-apply/rebasing" ]; then
 + __git_eread "$g/rebase-apply/head-name" b
 + r="|REBASE"
 + elif [ -f "$g/rebase-apply/applying" ]; then
 + r="|AM"
 + else
 + r="|AM/REBASE"
 + fi
 + elif [ -f "$g/MERGE_HEAD" ]; then
 + r="|MERGING"
 + elif __git_sequencer_status; then
 + :
 + elif [ -f "$g/BISECT_LOG" ]; then
 + r="|BISECTING"
 + fi
 +
 + if [ -n "$b" ]; then
 + :
 + elif [ -h "$g/HEAD" ]; then
 + # symlink symbolic ref
 + b="$(git symbolic-ref HEAD 2>/dev/null)"
 + else
 + local head=""
 +
 + case "$ref_format" in
 + files)
 + if ! __git_eread "$g/HEAD" head; then
 + return $exit
 + fi
 +
 + if [[ $head == "ref: "* ]]; then
 + head="${head#ref: }"
 + else
 + head=""
 + fi
 + ;;
 + *)
 + head="$(git symbolic-ref HEAD 2>/dev/null)"
 + ;;
 + esac
 +
 + if test -z "$head"; then
 + detached=yes
 + b="$(
 + case "${GIT_PS1_DESCRIBE_STYLE-}" in
 + (contains)
 + git describe --contains HEAD ;;
 + (branch)
 + git describe --contains --all HEAD ;;
 + (tag)
 + git describe --tags HEAD ;;
 + (describe)
 + git describe HEAD ;;
 + (* | default)
 + git describe --tags --exact-match HEAD ;;
 + esac 2>/dev/null)" ||
 +
 + b="$short_sha..."
 + b="($b)"
 + else
 + b="$head"
 + fi
 + fi
 + fi
 +
 + if [ -n "$step" ] && [ -n "$total" ]; then
 + r="$r $step/$total"
 + fi
 +
 + local conflict="" # state indicator for unresolved conflicts
 + if [[ "${GIT_PS1_SHOWCONFLICTSTATE}" == "yes" ]] &&
 +    [[ $(git ls-files --unmerged 2>/dev/null) ]]; then
 + conflict="|CONFLICT"
 + fi
 +
 + local w=""
 + local i=""
 + local s=""
 + local u=""
 + local h=""
 + local c=""
 + local p="" # short version of upstream state indicator
 + local upstream="" # verbose version of upstream state indicator
 +
 + if [ "true" = "$inside_gitdir" ]; then
 + if [ "true" = "$bare_repo" ]; then
 + c="BARE:"
 + else
 + b="GIT_DIR!"
 + fi
 + elif [ "true" = "$inside_worktree" ]; then
 + if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
 +    [ "$(git config --bool bash.showDirtyState)" != "false" ]
 + then
 + git diff --no-ext-diff --quiet || w="*"
 + git diff --no-ext-diff --cached --quiet || i="+"
 + if [ -z "$short_sha" ] && [ -z "$i" ]; then
 + i="#"
 + fi
 + fi
 + if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ] &&
 +    git rev-parse --verify --quiet refs/stash >/dev/null
 + then
 + s="$"
 + fi
 +
 + if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
 +    [ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
 +    git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null
 + then
 + u="%${ZSH_VERSION+%}"
 + fi
 +
 + if [ -n "${GIT_PS1_COMPRESSSPARSESTATE-}" ] &&
 +    [ "$(git config --bool core.sparseCheckout)" = "true" ]; then
 + h="?"
 + fi
 +
 + if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
 + __git_ps1_show_upstream
 + fi
 + fi
 +
 + local z="${GIT_PS1_STATESEPARATOR-" "}"
 +
 + b=${b##refs/heads/}
 + if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
 + __git_ps1_branch_name=$b
 + b="\${__git_ps1_branch_name}"
 + fi
 +
 + if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
 + __git_ps1_colorize_gitstring
 + fi
 +
 + local f="$h$w$i$s$u$p"
 + local gitstring="$c$b${f:+$z$f}${sparse}$r${upstream}${conflict}"
 +
 + if [ $pcmode = yes ]; then
 + if [ "${__git_printf_supports_v-}" != yes ]; then
 + gitstring=$(printf -- "$printf_format" "$gitstring")
 + else
 + printf -v gitstring -- "$printf_format" "$gitstring"
 + fi
 + PS1="$ps1pc_start$gitstring$ps1pc_end"
 + else
 + printf -- "$printf_format" "$gitstring"
 + fi
 +
 + return $exit
 +}
 +</code>