contrib / completion / git-completion.bashon commit Merge branch 'tr/maint-mailinfo' (b51ffa8)
   1#!bash
   2#
   3# bash/zsh completion support for core Git.
   4#
   5# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
   6# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
   7# Distributed under the GNU General Public License, version 2.0.
   8#
   9# The contained completion routines provide support for completing:
  10#
  11#    *) local and remote branch names
  12#    *) local and remote tag names
  13#    *) .git/remotes file names
  14#    *) git 'subcommands'
  15#    *) tree paths within 'ref:path/to/file' expressions
  16#    *) common --long-options
  17#
  18# To use these routines:
  19#
  20#    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
  21#    2) Add the following line to your .bashrc/.zshrc:
  22#        source ~/.git-completion.sh
  23#
  24#    3) Consider changing your PS1 to also show the current branch:
  25#         Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
  26#         ZSH:  PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
  27#
  28#       The argument to __git_ps1 will be displayed only if you
  29#       are currently in a git repository.  The %s token will be
  30#       the name of the current branch.
  31#
  32#       In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty
  33#       value, unstaged (*) and staged (+) changes will be shown next
  34#       to the branch name.  You can configure this per-repository
  35#       with the bash.showDirtyState variable, which defaults to true
  36#       once GIT_PS1_SHOWDIRTYSTATE is enabled.
  37#
  38#       You can also see if currently something is stashed, by setting
  39#       GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
  40#       then a '$' will be shown next to the branch name.
  41#
  42#       If you would like to see if there're untracked files, then you can
  43#       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
  44#       untracked files, then a '%' will be shown next to the branch name.
  45#
  46#       If you would like to see the difference between HEAD and its
  47#       upstream, set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates
  48#       you are behind, ">" indicates you are ahead, and "<>"
  49#       indicates you have diverged.  You can further control
  50#       behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated
  51#       list of values:
  52#           verbose       show number of commits ahead/behind (+/-) upstream
  53#           legacy        don't use the '--count' option available in recent
  54#                         versions of git-rev-list
  55#           git           always compare HEAD to @{upstream}
  56#           svn           always compare HEAD to your SVN upstream
  57#       By default, __git_ps1 will compare HEAD to your SVN upstream
  58#       if it can find one, or @{upstream} otherwise.  Once you have
  59#       set GIT_PS1_SHOWUPSTREAM, you can override it on a
  60#       per-repository basis by setting the bash.showUpstream config
  61#       variable.
  62#
  63#
  64# To submit patches:
  65#
  66#    *) Read Documentation/SubmittingPatches
  67#    *) Send all patches to the current maintainer:
  68#
  69#       "Shawn O. Pearce" <spearce@spearce.org>
  70#
  71#    *) Always CC the Git mailing list:
  72#
  73#       git@vger.kernel.org
  74#
  75
  76if [[ -n ${ZSH_VERSION-} ]]; then
  77        autoload -U +X bashcompinit && bashcompinit
  78fi
  79
  80case "$COMP_WORDBREAKS" in
  81*:*) : great ;;
  82*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
  83esac
  84
  85# __gitdir accepts 0 or 1 arguments (i.e., location)
  86# returns location of .git repo
  87__gitdir ()
  88{
  89        if [ -z "${1-}" ]; then
  90                if [ -n "${__git_dir-}" ]; then
  91                        echo "$__git_dir"
  92                elif [ -d .git ]; then
  93                        echo .git
  94                else
  95                        git rev-parse --git-dir 2>/dev/null
  96                fi
  97        elif [ -d "$1/.git" ]; then
  98                echo "$1/.git"
  99        else
 100                echo "$1"
 101        fi
 102}
 103
 104# stores the divergence from upstream in $p
 105# used by GIT_PS1_SHOWUPSTREAM
 106__git_ps1_show_upstream ()
 107{
 108        local key value
 109        local svn_remote=() svn_url_pattern count n
 110        local upstream=git legacy="" verbose=""
 111
 112        # get some config options from git-config
 113        local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
 114        while read -r key value; do
 115                case "$key" in
 116                bash.showupstream)
 117                        GIT_PS1_SHOWUPSTREAM="$value"
 118                        if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
 119                                p=""
 120                                return
 121                        fi
 122                        ;;
 123                svn-remote.*.url)
 124                        svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
 125                        svn_url_pattern+="\\|$value"
 126                        upstream=svn+git # default upstream is SVN if available, else git
 127                        ;;
 128                esac
 129        done <<< "$output"
 130
 131        # parse configuration values
 132        for option in ${GIT_PS1_SHOWUPSTREAM}; do
 133                case "$option" in
 134                git|svn) upstream="$option" ;;
 135                verbose) verbose=1 ;;
 136                legacy)  legacy=1  ;;
 137                esac
 138        done
 139
 140        # Find our upstream
 141        case "$upstream" in
 142        git)    upstream="@{upstream}" ;;
 143        svn*)
 144                # get the upstream from the "git-svn-id: ..." in a commit message
 145                # (git-svn uses essentially the same procedure internally)
 146                local svn_upstream=($(git log --first-parent -1 \
 147                                        --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
 148                if [[ 0 -ne ${#svn_upstream[@]} ]]; then
 149                        svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
 150                        svn_upstream=${svn_upstream%@*}
 151                        local n_stop="${#svn_remote[@]}"
 152                        for ((n=1; n <= n_stop; ++n)); do
 153                                svn_upstream=${svn_upstream#${svn_remote[$n]}}
 154                        done
 155
 156                        if [[ -z "$svn_upstream" ]]; then
 157                                # default branch name for checkouts with no layout:
 158                                upstream=${GIT_SVN_ID:-git-svn}
 159                        else
 160                                upstream=${svn_upstream#/}
 161                        fi
 162                elif [[ "svn+git" = "$upstream" ]]; then
 163                        upstream="@{upstream}"
 164                fi
 165                ;;
 166        esac
 167
 168        # Find how many commits we are ahead/behind our upstream
 169        if [[ -z "$legacy" ]]; then
 170                count="$(git rev-list --count --left-right \
 171                                "$upstream"...HEAD 2>/dev/null)"
 172        else
 173                # produce equivalent output to --count for older versions of git
 174                local commits
 175                if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
 176                then
 177                        local commit behind=0 ahead=0
 178                        for commit in $commits
 179                        do
 180                                case "$commit" in
 181                                "<"*) let ++behind
 182                                        ;;
 183                                *)    let ++ahead
 184                                        ;;
 185                                esac
 186                        done
 187                        count="$behind  $ahead"
 188                else
 189                        count=""
 190                fi
 191        fi
 192
 193        # calculate the result
 194        if [[ -z "$verbose" ]]; then
 195                case "$count" in
 196                "") # no upstream
 197                        p="" ;;
 198                "0      0") # equal to upstream
 199                        p="=" ;;
 200                "0      "*) # ahead of upstream
 201                        p=">" ;;
 202                *"      0") # behind upstream
 203                        p="<" ;;
 204                *)          # diverged from upstream
 205                        p="<>" ;;
 206                esac
 207        else
 208                case "$count" in
 209                "") # no upstream
 210                        p="" ;;
 211                "0      0") # equal to upstream
 212                        p=" u=" ;;
 213                "0      "*) # ahead of upstream
 214                        p=" u+${count#0 }" ;;
 215                *"      0") # behind upstream
 216                        p=" u-${count%  0}" ;;
 217                *)          # diverged from upstream
 218                        p=" u+${count#* }-${count%      *}" ;;
 219                esac
 220        fi
 221
 222}
 223
 224
 225# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
 226# returns text to add to bash PS1 prompt (includes branch name)
 227__git_ps1 ()
 228{
 229        local g="$(__gitdir)"
 230        if [ -n "$g" ]; then
 231                local r=""
 232                local b=""
 233                if [ -f "$g/rebase-merge/interactive" ]; then
 234                        r="|REBASE-i"
 235                        b="$(cat "$g/rebase-merge/head-name")"
 236                elif [ -d "$g/rebase-merge" ]; then
 237                        r="|REBASE-m"
 238                        b="$(cat "$g/rebase-merge/head-name")"
 239                else
 240                        if [ -d "$g/rebase-apply" ]; then
 241                                if [ -f "$g/rebase-apply/rebasing" ]; then
 242                                        r="|REBASE"
 243                                elif [ -f "$g/rebase-apply/applying" ]; then
 244                                        r="|AM"
 245                                else
 246                                        r="|AM/REBASE"
 247                                fi
 248                        elif [ -f "$g/MERGE_HEAD" ]; then
 249                                r="|MERGING"
 250                        elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
 251                                r="|CHERRY-PICKING"
 252                        elif [ -f "$g/BISECT_LOG" ]; then
 253                                r="|BISECTING"
 254                        fi
 255
 256                        b="$(git symbolic-ref HEAD 2>/dev/null)" || {
 257
 258                                b="$(
 259                                case "${GIT_PS1_DESCRIBE_STYLE-}" in
 260                                (contains)
 261                                        git describe --contains HEAD ;;
 262                                (branch)
 263                                        git describe --contains --all HEAD ;;
 264                                (describe)
 265                                        git describe HEAD ;;
 266                                (* | default)
 267                                        git describe --tags --exact-match HEAD ;;
 268                                esac 2>/dev/null)" ||
 269
 270                                b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
 271                                b="unknown"
 272                                b="($b)"
 273                        }
 274                fi
 275
 276                local w=""
 277                local i=""
 278                local s=""
 279                local u=""
 280                local c=""
 281                local p=""
 282
 283                if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
 284                        if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
 285                                c="BARE:"
 286                        else
 287                                b="GIT_DIR!"
 288                        fi
 289                elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
 290                        if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
 291                                if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
 292                                        git diff --no-ext-diff --quiet --exit-code || w="*"
 293                                        if git rev-parse --quiet --verify HEAD >/dev/null; then
 294                                                git diff-index --cached --quiet HEAD -- || i="+"
 295                                        else
 296                                                i="#"
 297                                        fi
 298                                fi
 299                        fi
 300                        if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
 301                                git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
 302                        fi
 303
 304                        if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
 305                           if [ -n "$(git ls-files --others --exclude-standard)" ]; then
 306                              u="%"
 307                           fi
 308                        fi
 309
 310                        if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
 311                                __git_ps1_show_upstream
 312                        fi
 313                fi
 314
 315                local f="$w$i$s$u"
 316                printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
 317        fi
 318}
 319
 320# __gitcomp_1 requires 2 arguments
 321__gitcomp_1 ()
 322{
 323        local c IFS=' '$'\t'$'\n'
 324        for c in $1; do
 325                case "$c$2" in
 326                --*=*) printf %s$'\n' "$c$2" ;;
 327                *.)    printf %s$'\n' "$c$2" ;;
 328                *)     printf %s$'\n' "$c$2 " ;;
 329                esac
 330        done
 331}
 332
 333# The following function is based on code from:
 334#
 335#   bash_completion - programmable completion functions for bash 3.2+
 336#
 337#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
 338#             © 2009-2010, Bash Completion Maintainers
 339#                     <bash-completion-devel@lists.alioth.debian.org>
 340#
 341#   This program is free software; you can redistribute it and/or modify
 342#   it under the terms of the GNU General Public License as published by
 343#   the Free Software Foundation; either version 2, or (at your option)
 344#   any later version.
 345#
 346#   This program is distributed in the hope that it will be useful,
 347#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 348#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 349#   GNU General Public License for more details.
 350#
 351#   You should have received a copy of the GNU General Public License
 352#   along with this program; if not, write to the Free Software Foundation,
 353#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 354#
 355#   The latest version of this software can be obtained here:
 356#
 357#   http://bash-completion.alioth.debian.org/
 358#
 359#   RELEASE: 2.x
 360
 361# This function can be used to access a tokenized list of words
 362# on the command line:
 363#
 364#       __git_reassemble_comp_words_by_ref '=:'
 365#       if test "${words_[cword_-1]}" = -w
 366#       then
 367#               ...
 368#       fi
 369#
 370# The argument should be a collection of characters from the list of
 371# word completion separators (COMP_WORDBREAKS) to treat as ordinary
 372# characters.
 373#
 374# This is roughly equivalent to going back in time and setting
 375# COMP_WORDBREAKS to exclude those characters.  The intent is to
 376# make option types like --date=<type> and <rev>:<path> easy to
 377# recognize by treating each shell word as a single token.
 378#
 379# It is best not to set COMP_WORDBREAKS directly because the value is
 380# shared with other completion scripts.  By the time the completion
 381# function gets called, COMP_WORDS has already been populated so local
 382# changes to COMP_WORDBREAKS have no effect.
 383#
 384# Output: words_, cword_, cur_.
 385
 386__git_reassemble_comp_words_by_ref()
 387{
 388        local exclude i j first
 389        # Which word separators to exclude?
 390        exclude="${1//[^$COMP_WORDBREAKS]}"
 391        cword_=$COMP_CWORD
 392        if [ -z "$exclude" ]; then
 393                words_=("${COMP_WORDS[@]}")
 394                return
 395        fi
 396        # List of word completion separators has shrunk;
 397        # re-assemble words to complete.
 398        for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
 399                # Append each nonempty word consisting of just
 400                # word separator characters to the current word.
 401                first=t
 402                while
 403                        [ $i -gt 0 ] &&
 404                        [ -n "${COMP_WORDS[$i]}" ] &&
 405                        # word consists of excluded word separators
 406                        [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
 407                do
 408                        # Attach to the previous token,
 409                        # unless the previous token is the command name.
 410                        if [ $j -ge 2 ] && [ -n "$first" ]; then
 411                                ((j--))
 412                        fi
 413                        first=
 414                        words_[$j]=${words_[j]}${COMP_WORDS[i]}
 415                        if [ $i = $COMP_CWORD ]; then
 416                                cword_=$j
 417                        fi
 418                        if (($i < ${#COMP_WORDS[@]} - 1)); then
 419                                ((i++))
 420                        else
 421                                # Done.
 422                                return
 423                        fi
 424                done
 425                words_[$j]=${words_[j]}${COMP_WORDS[i]}
 426                if [ $i = $COMP_CWORD ]; then
 427                        cword_=$j
 428                fi
 429        done
 430}
 431
 432if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
 433if [[ -z ${ZSH_VERSION:+set} ]]; then
 434_get_comp_words_by_ref ()
 435{
 436        local exclude cur_ words_ cword_
 437        if [ "$1" = "-n" ]; then
 438                exclude=$2
 439                shift 2
 440        fi
 441        __git_reassemble_comp_words_by_ref "$exclude"
 442        cur_=${words_[cword_]}
 443        while [ $# -gt 0 ]; do
 444                case "$1" in
 445                cur)
 446                        cur=$cur_
 447                        ;;
 448                prev)
 449                        prev=${words_[$cword_-1]}
 450                        ;;
 451                words)
 452                        words=("${words_[@]}")
 453                        ;;
 454                cword)
 455                        cword=$cword_
 456                        ;;
 457                esac
 458                shift
 459        done
 460}
 461else
 462_get_comp_words_by_ref ()
 463{
 464        while [ $# -gt 0 ]; do
 465                case "$1" in
 466                cur)
 467                        cur=${COMP_WORDS[COMP_CWORD]}
 468                        ;;
 469                prev)
 470                        prev=${COMP_WORDS[COMP_CWORD-1]}
 471                        ;;
 472                words)
 473                        words=("${COMP_WORDS[@]}")
 474                        ;;
 475                cword)
 476                        cword=$COMP_CWORD
 477                        ;;
 478                -n)
 479                        # assume COMP_WORDBREAKS is already set sanely
 480                        shift
 481                        ;;
 482                esac
 483                shift
 484        done
 485}
 486fi
 487fi
 488
 489# Generates completion reply with compgen, appending a space to possible
 490# completion words, if necessary.
 491# It accepts 1 to 4 arguments:
 492# 1: List of possible completion words.
 493# 2: A prefix to be added to each possible completion word (optional).
 494# 3: Generate possible completion matches for this word (optional).
 495# 4: A suffix to be appended to each possible completion word (optional).
 496__gitcomp ()
 497{
 498        local cur_="$cur"
 499
 500        if [ $# -gt 2 ]; then
 501                cur_="$3"
 502        fi
 503        case "$cur_" in
 504        --*=)
 505                COMPREPLY=()
 506                ;;
 507        *)
 508                local IFS=$'\n'
 509                COMPREPLY=($(compgen -P "${2-}" \
 510                        -W "$(__gitcomp_1 "${1-}" "${4-}")" \
 511                        -- "$cur_"))
 512                ;;
 513        esac
 514}
 515
 516# Generates completion reply with compgen from newline-separated possible
 517# completion words by appending a space to all of them.
 518# It accepts 1 to 4 arguments:
 519# 1: List of possible completion words, separated by a single newline.
 520# 2: A prefix to be added to each possible completion word (optional).
 521# 3: Generate possible completion matches for this word (optional).
 522# 4: A suffix to be appended to each possible completion word instead of
 523#    the default space (optional).  If specified but empty, nothing is
 524#    appended.
 525__gitcomp_nl ()
 526{
 527        local s=$'\n' IFS=' '$'\t'$'\n'
 528        local cur_="$cur" suffix=" "
 529
 530        if [ $# -gt 2 ]; then
 531                cur_="$3"
 532                if [ $# -gt 3 ]; then
 533                        suffix="$4"
 534                fi
 535        fi
 536
 537        IFS=$s
 538        COMPREPLY=($(compgen -P "${2-}" -S "$suffix" -W "$1" -- "$cur_"))
 539}
 540
 541__git_heads ()
 542{
 543        local dir="$(__gitdir)"
 544        if [ -d "$dir" ]; then
 545                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
 546                        refs/heads
 547                return
 548        fi
 549}
 550
 551__git_tags ()
 552{
 553        local dir="$(__gitdir)"
 554        if [ -d "$dir" ]; then
 555                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
 556                        refs/tags
 557                return
 558        fi
 559}
 560
 561# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
 562# presence of 2nd argument means use the guess heuristic employed
 563# by checkout for tracking branches
 564__git_refs ()
 565{
 566        local i hash dir="$(__gitdir "${1-}")" track="${2-}"
 567        local format refs
 568        if [ -d "$dir" ]; then
 569                case "$cur" in
 570                refs|refs/*)
 571                        format="refname"
 572                        refs="${cur%/*}"
 573                        track=""
 574                        ;;
 575                *)
 576                        for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
 577                                if [ -e "$dir/$i" ]; then echo $i; fi
 578                        done
 579                        format="refname:short"
 580                        refs="refs/tags refs/heads refs/remotes"
 581                        ;;
 582                esac
 583                git --git-dir="$dir" for-each-ref --format="%($format)" \
 584                        $refs
 585                if [ -n "$track" ]; then
 586                        # employ the heuristic used by git checkout
 587                        # Try to find a remote branch that matches the completion word
 588                        # but only output if the branch name is unique
 589                        local ref entry
 590                        git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \
 591                                "refs/remotes/" | \
 592                        while read -r entry; do
 593                                eval "$entry"
 594                                ref="${ref#*/}"
 595                                if [[ "$ref" == "$cur"* ]]; then
 596                                        echo "$ref"
 597                                fi
 598                        done | uniq -u
 599                fi
 600                return
 601        fi
 602        case "$cur" in
 603        refs|refs/*)
 604                git ls-remote "$dir" "$cur*" 2>/dev/null | \
 605                while read -r hash i; do
 606                        case "$i" in
 607                        *^{}) ;;
 608                        *) echo "$i" ;;
 609                        esac
 610                done
 611                ;;
 612        *)
 613                git ls-remote "$dir" HEAD ORIG_HEAD 'refs/tags/*' 'refs/heads/*' 'refs/remotes/*' 2>/dev/null | \
 614                while read -r hash i; do
 615                        case "$i" in
 616                        *^{}) ;;
 617                        refs/*) echo "${i#refs/*/}" ;;
 618                        *) echo "$i" ;;
 619                        esac
 620                done
 621                ;;
 622        esac
 623}
 624
 625# __git_refs2 requires 1 argument (to pass to __git_refs)
 626__git_refs2 ()
 627{
 628        local i
 629        for i in $(__git_refs "$1"); do
 630                echo "$i:$i"
 631        done
 632}
 633
 634# __git_refs_remotes requires 1 argument (to pass to ls-remote)
 635__git_refs_remotes ()
 636{
 637        local i hash
 638        git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
 639        while read -r hash i; do
 640                echo "$i:refs/remotes/$1/${i#refs/heads/}"
 641        done
 642}
 643
 644__git_remotes ()
 645{
 646        local i ngoff IFS=$'\n' d="$(__gitdir)"
 647        __git_shopt -q nullglob || ngoff=1
 648        __git_shopt -s nullglob
 649        for i in "$d/remotes"/*; do
 650                echo ${i#$d/remotes/}
 651        done
 652        [ "$ngoff" ] && __git_shopt -u nullglob
 653        for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
 654                i="${i#remote.}"
 655                echo "${i/.url*/}"
 656        done
 657}
 658
 659__git_list_merge_strategies ()
 660{
 661        git merge -s help 2>&1 |
 662        sed -n -e '/[Aa]vailable strategies are: /,/^$/{
 663                s/\.$//
 664                s/.*://
 665                s/^[    ]*//
 666                s/[     ]*$//
 667                p
 668        }'
 669}
 670
 671__git_merge_strategies=
 672# 'git merge -s help' (and thus detection of the merge strategy
 673# list) fails, unfortunately, if run outside of any git working
 674# tree.  __git_merge_strategies is set to the empty string in
 675# that case, and the detection will be repeated the next time it
 676# is needed.
 677__git_compute_merge_strategies ()
 678{
 679        : ${__git_merge_strategies:=$(__git_list_merge_strategies)}
 680}
 681
 682__git_complete_revlist_file ()
 683{
 684        local pfx ls ref cur_="$cur"
 685        case "$cur_" in
 686        *..?*:*)
 687                return
 688                ;;
 689        ?*:*)
 690                ref="${cur_%%:*}"
 691                cur_="${cur_#*:}"
 692                case "$cur_" in
 693                ?*/*)
 694                        pfx="${cur_%/*}"
 695                        cur_="${cur_##*/}"
 696                        ls="$ref:$pfx"
 697                        pfx="$pfx/"
 698                        ;;
 699                *)
 700                        ls="$ref"
 701                        ;;
 702                esac
 703
 704                case "$COMP_WORDBREAKS" in
 705                *:*) : great ;;
 706                *)   pfx="$ref:$pfx" ;;
 707                esac
 708
 709                local IFS=$'\n'
 710                COMPREPLY=($(compgen -P "$pfx" \
 711                        -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
 712                                | sed '/^100... blob /{
 713                                           s,^.*        ,,
 714                                           s,$, ,
 715                                       }
 716                                       /^120000 blob /{
 717                                           s,^.*        ,,
 718                                           s,$, ,
 719                                       }
 720                                       /^040000 tree /{
 721                                           s,^.*        ,,
 722                                           s,$,/,
 723                                       }
 724                                       s/^.*    //')" \
 725                        -- "$cur_"))
 726                ;;
 727        *...*)
 728                pfx="${cur_%...*}..."
 729                cur_="${cur_#*...}"
 730                __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 731                ;;
 732        *..*)
 733                pfx="${cur_%..*}.."
 734                cur_="${cur_#*..}"
 735                __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 736                ;;
 737        *)
 738                __gitcomp_nl "$(__git_refs)"
 739                ;;
 740        esac
 741}
 742
 743
 744__git_complete_file ()
 745{
 746        __git_complete_revlist_file
 747}
 748
 749__git_complete_revlist ()
 750{
 751        __git_complete_revlist_file
 752}
 753
 754__git_complete_remote_or_refspec ()
 755{
 756        local cur_="$cur" cmd="${words[1]}"
 757        local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
 758        while [ $c -lt $cword ]; do
 759                i="${words[c]}"
 760                case "$i" in
 761                --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
 762                --all)
 763                        case "$cmd" in
 764                        push) no_complete_refspec=1 ;;
 765                        fetch)
 766                                COMPREPLY=()
 767                                return
 768                                ;;
 769                        *) ;;
 770                        esac
 771                        ;;
 772                -*) ;;
 773                *) remote="$i"; break ;;
 774                esac
 775                c=$((++c))
 776        done
 777        if [ -z "$remote" ]; then
 778                __gitcomp_nl "$(__git_remotes)"
 779                return
 780        fi
 781        if [ $no_complete_refspec = 1 ]; then
 782                COMPREPLY=()
 783                return
 784        fi
 785        [ "$remote" = "." ] && remote=
 786        case "$cur_" in
 787        *:*)
 788                case "$COMP_WORDBREAKS" in
 789                *:*) : great ;;
 790                *)   pfx="${cur_%%:*}:" ;;
 791                esac
 792                cur_="${cur_#*:}"
 793                lhs=0
 794                ;;
 795        +*)
 796                pfx="+"
 797                cur_="${cur_#+}"
 798                ;;
 799        esac
 800        case "$cmd" in
 801        fetch)
 802                if [ $lhs = 1 ]; then
 803                        __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
 804                else
 805                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 806                fi
 807                ;;
 808        pull)
 809                if [ $lhs = 1 ]; then
 810                        __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
 811                else
 812                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 813                fi
 814                ;;
 815        push)
 816                if [ $lhs = 1 ]; then
 817                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 818                else
 819                        __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
 820                fi
 821                ;;
 822        esac
 823}
 824
 825__git_complete_strategy ()
 826{
 827        __git_compute_merge_strategies
 828        case "$prev" in
 829        -s|--strategy)
 830                __gitcomp "$__git_merge_strategies"
 831                return 0
 832        esac
 833        case "$cur" in
 834        --strategy=*)
 835                __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
 836                return 0
 837                ;;
 838        esac
 839        return 1
 840}
 841
 842__git_list_all_commands ()
 843{
 844        local i IFS=" "$'\n'
 845        for i in $(git help -a|egrep '^  [a-zA-Z0-9]')
 846        do
 847                case $i in
 848                *--*)             : helper pattern;;
 849                *) echo $i;;
 850                esac
 851        done
 852}
 853
 854__git_all_commands=
 855__git_compute_all_commands ()
 856{
 857        : ${__git_all_commands:=$(__git_list_all_commands)}
 858}
 859
 860__git_list_porcelain_commands ()
 861{
 862        local i IFS=" "$'\n'
 863        __git_compute_all_commands
 864        for i in "help" $__git_all_commands
 865        do
 866                case $i in
 867                *--*)             : helper pattern;;
 868                applymbox)        : ask gittus;;
 869                applypatch)       : ask gittus;;
 870                archimport)       : import;;
 871                cat-file)         : plumbing;;
 872                check-attr)       : plumbing;;
 873                check-ref-format) : plumbing;;
 874                checkout-index)   : plumbing;;
 875                commit-tree)      : plumbing;;
 876                count-objects)    : infrequent;;
 877                cvsexportcommit)  : export;;
 878                cvsimport)        : import;;
 879                cvsserver)        : daemon;;
 880                daemon)           : daemon;;
 881                diff-files)       : plumbing;;
 882                diff-index)       : plumbing;;
 883                diff-tree)        : plumbing;;
 884                fast-import)      : import;;
 885                fast-export)      : export;;
 886                fsck-objects)     : plumbing;;
 887                fetch-pack)       : plumbing;;
 888                fmt-merge-msg)    : plumbing;;
 889                for-each-ref)     : plumbing;;
 890                hash-object)      : plumbing;;
 891                http-*)           : transport;;
 892                index-pack)       : plumbing;;
 893                init-db)          : deprecated;;
 894                local-fetch)      : plumbing;;
 895                lost-found)       : infrequent;;
 896                ls-files)         : plumbing;;
 897                ls-remote)        : plumbing;;
 898                ls-tree)          : plumbing;;
 899                mailinfo)         : plumbing;;
 900                mailsplit)        : plumbing;;
 901                merge-*)          : plumbing;;
 902                mktree)           : plumbing;;
 903                mktag)            : plumbing;;
 904                pack-objects)     : plumbing;;
 905                pack-redundant)   : plumbing;;
 906                pack-refs)        : plumbing;;
 907                parse-remote)     : plumbing;;
 908                patch-id)         : plumbing;;
 909                peek-remote)      : plumbing;;
 910                prune)            : plumbing;;
 911                prune-packed)     : plumbing;;
 912                quiltimport)      : import;;
 913                read-tree)        : plumbing;;
 914                receive-pack)     : plumbing;;
 915                remote-*)         : transport;;
 916                repo-config)      : deprecated;;
 917                rerere)           : plumbing;;
 918                rev-list)         : plumbing;;
 919                rev-parse)        : plumbing;;
 920                runstatus)        : plumbing;;
 921                sh-setup)         : internal;;
 922                shell)            : daemon;;
 923                show-ref)         : plumbing;;
 924                send-pack)        : plumbing;;
 925                show-index)       : plumbing;;
 926                ssh-*)            : transport;;
 927                stripspace)       : plumbing;;
 928                symbolic-ref)     : plumbing;;
 929                tar-tree)         : deprecated;;
 930                unpack-file)      : plumbing;;
 931                unpack-objects)   : plumbing;;
 932                update-index)     : plumbing;;
 933                update-ref)       : plumbing;;
 934                update-server-info) : daemon;;
 935                upload-archive)   : plumbing;;
 936                upload-pack)      : plumbing;;
 937                write-tree)       : plumbing;;
 938                var)              : infrequent;;
 939                verify-pack)      : infrequent;;
 940                verify-tag)       : plumbing;;
 941                *) echo $i;;
 942                esac
 943        done
 944}
 945
 946__git_porcelain_commands=
 947__git_compute_porcelain_commands ()
 948{
 949        __git_compute_all_commands
 950        : ${__git_porcelain_commands:=$(__git_list_porcelain_commands)}
 951}
 952
 953__git_pretty_aliases ()
 954{
 955        local i IFS=$'\n'
 956        for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do
 957                case "$i" in
 958                pretty.*)
 959                        i="${i#pretty.}"
 960                        echo "${i/ */}"
 961                        ;;
 962                esac
 963        done
 964}
 965
 966__git_aliases ()
 967{
 968        local i IFS=$'\n'
 969        for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
 970                case "$i" in
 971                alias.*)
 972                        i="${i#alias.}"
 973                        echo "${i/ */}"
 974                        ;;
 975                esac
 976        done
 977}
 978
 979# __git_aliased_command requires 1 argument
 980__git_aliased_command ()
 981{
 982        local word cmdline=$(git --git-dir="$(__gitdir)" \
 983                config --get "alias.$1")
 984        for word in $cmdline; do
 985                case "$word" in
 986                \!gitk|gitk)
 987                        echo "gitk"
 988                        return
 989                        ;;
 990                \!*)    : shell command alias ;;
 991                -*)     : option ;;
 992                *=*)    : setting env ;;
 993                git)    : git itself ;;
 994                *)
 995                        echo "$word"
 996                        return
 997                esac
 998        done
 999}
1000
1001# __git_find_on_cmdline requires 1 argument
1002__git_find_on_cmdline ()
1003{
1004        local word subcommand c=1
1005        while [ $c -lt $cword ]; do
1006                word="${words[c]}"
1007                for subcommand in $1; do
1008                        if [ "$subcommand" = "$word" ]; then
1009                                echo "$subcommand"
1010                                return
1011                        fi
1012                done
1013                c=$((++c))
1014        done
1015}
1016
1017__git_has_doubledash ()
1018{
1019        local c=1
1020        while [ $c -lt $cword ]; do
1021                if [ "--" = "${words[c]}" ]; then
1022                        return 0
1023                fi
1024                c=$((++c))
1025        done
1026        return 1
1027}
1028
1029__git_whitespacelist="nowarn warn error error-all fix"
1030
1031_git_am ()
1032{
1033        local dir="$(__gitdir)"
1034        if [ -d "$dir"/rebase-apply ]; then
1035                __gitcomp "--skip --continue --resolved --abort"
1036                return
1037        fi
1038        case "$cur" in
1039        --whitespace=*)
1040                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1041                return
1042                ;;
1043        --*)
1044                __gitcomp "
1045                        --3way --committer-date-is-author-date --ignore-date
1046                        --ignore-whitespace --ignore-space-change
1047                        --interactive --keep --no-utf8 --signoff --utf8
1048                        --whitespace= --scissors
1049                        "
1050                return
1051        esac
1052        COMPREPLY=()
1053}
1054
1055_git_apply ()
1056{
1057        case "$cur" in
1058        --whitespace=*)
1059                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1060                return
1061                ;;
1062        --*)
1063                __gitcomp "
1064                        --stat --numstat --summary --check --index
1065                        --cached --index-info --reverse --reject --unidiff-zero
1066                        --apply --no-add --exclude=
1067                        --ignore-whitespace --ignore-space-change
1068                        --whitespace= --inaccurate-eof --verbose
1069                        "
1070                return
1071        esac
1072        COMPREPLY=()
1073}
1074
1075_git_add ()
1076{
1077        __git_has_doubledash && return
1078
1079        case "$cur" in
1080        --*)
1081                __gitcomp "
1082                        --interactive --refresh --patch --update --dry-run
1083                        --ignore-errors --intent-to-add
1084                        "
1085                return
1086        esac
1087        COMPREPLY=()
1088}
1089
1090_git_archive ()
1091{
1092        case "$cur" in
1093        --format=*)
1094                __gitcomp "$(git archive --list)" "" "${cur##--format=}"
1095                return
1096                ;;
1097        --remote=*)
1098                __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
1099                return
1100                ;;
1101        --*)
1102                __gitcomp "
1103                        --format= --list --verbose
1104                        --prefix= --remote= --exec=
1105                        "
1106                return
1107                ;;
1108        esac
1109        __git_complete_file
1110}
1111
1112_git_bisect ()
1113{
1114        __git_has_doubledash && return
1115
1116        local subcommands="start bad good skip reset visualize replay log run"
1117        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1118        if [ -z "$subcommand" ]; then
1119                if [ -f "$(__gitdir)"/BISECT_START ]; then
1120                        __gitcomp "$subcommands"
1121                else
1122                        __gitcomp "replay start"
1123                fi
1124                return
1125        fi
1126
1127        case "$subcommand" in
1128        bad|good|reset|skip|start)
1129                __gitcomp_nl "$(__git_refs)"
1130                ;;
1131        *)
1132                COMPREPLY=()
1133                ;;
1134        esac
1135}
1136
1137_git_branch ()
1138{
1139        local i c=1 only_local_ref="n" has_r="n"
1140
1141        while [ $c -lt $cword ]; do
1142                i="${words[c]}"
1143                case "$i" in
1144                -d|-m)  only_local_ref="y" ;;
1145                -r)     has_r="y" ;;
1146                esac
1147                c=$((++c))
1148        done
1149
1150        case "$cur" in
1151        --*)
1152                __gitcomp "
1153                        --color --no-color --verbose --abbrev= --no-abbrev
1154                        --track --no-track --contains --merged --no-merged
1155                        --set-upstream
1156                        "
1157                ;;
1158        *)
1159                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
1160                        __gitcomp_nl "$(__git_heads)"
1161                else
1162                        __gitcomp_nl "$(__git_refs)"
1163                fi
1164                ;;
1165        esac
1166}
1167
1168_git_bundle ()
1169{
1170        local cmd="${words[2]}"
1171        case "$cword" in
1172        2)
1173                __gitcomp "create list-heads verify unbundle"
1174                ;;
1175        3)
1176                # looking for a file
1177                ;;
1178        *)
1179                case "$cmd" in
1180                        create)
1181                                __git_complete_revlist
1182                        ;;
1183                esac
1184                ;;
1185        esac
1186}
1187
1188_git_checkout ()
1189{
1190        __git_has_doubledash && return
1191
1192        case "$cur" in
1193        --conflict=*)
1194                __gitcomp "diff3 merge" "" "${cur##--conflict=}"
1195                ;;
1196        --*)
1197                __gitcomp "
1198                        --quiet --ours --theirs --track --no-track --merge
1199                        --conflict= --orphan --patch
1200                        "
1201                ;;
1202        *)
1203                # check if --track, --no-track, or --no-guess was specified
1204                # if so, disable DWIM mode
1205                local flags="--track --no-track --no-guess" track=1
1206                if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
1207                        track=''
1208                fi
1209                __gitcomp_nl "$(__git_refs '' $track)"
1210                ;;
1211        esac
1212}
1213
1214_git_cherry ()
1215{
1216        __gitcomp "$(__git_refs)"
1217}
1218
1219_git_cherry_pick ()
1220{
1221        case "$cur" in
1222        --*)
1223                __gitcomp "--edit --no-commit"
1224                ;;
1225        *)
1226                __gitcomp_nl "$(__git_refs)"
1227                ;;
1228        esac
1229}
1230
1231_git_clean ()
1232{
1233        __git_has_doubledash && return
1234
1235        case "$cur" in
1236        --*)
1237                __gitcomp "--dry-run --quiet"
1238                return
1239                ;;
1240        esac
1241        COMPREPLY=()
1242}
1243
1244_git_clone ()
1245{
1246        case "$cur" in
1247        --*)
1248                __gitcomp "
1249                        --local
1250                        --no-hardlinks
1251                        --shared
1252                        --reference
1253                        --quiet
1254                        --no-checkout
1255                        --bare
1256                        --mirror
1257                        --origin
1258                        --upload-pack
1259                        --template=
1260                        --depth
1261                        "
1262                return
1263                ;;
1264        esac
1265        COMPREPLY=()
1266}
1267
1268_git_commit ()
1269{
1270        __git_has_doubledash && return
1271
1272        case "$cur" in
1273        --cleanup=*)
1274                __gitcomp "default strip verbatim whitespace
1275                        " "" "${cur##--cleanup=}"
1276                return
1277                ;;
1278        --reuse-message=*|--reedit-message=*|\
1279        --fixup=*|--squash=*)
1280                __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1281                return
1282                ;;
1283        --untracked-files=*)
1284                __gitcomp "all no normal" "" "${cur##--untracked-files=}"
1285                return
1286                ;;
1287        --*)
1288                __gitcomp "
1289                        --all --author= --signoff --verify --no-verify
1290                        --edit --amend --include --only --interactive
1291                        --dry-run --reuse-message= --reedit-message=
1292                        --reset-author --file= --message= --template=
1293                        --cleanup= --untracked-files --untracked-files=
1294                        --verbose --quiet --fixup= --squash=
1295                        "
1296                return
1297        esac
1298        COMPREPLY=()
1299}
1300
1301_git_describe ()
1302{
1303        case "$cur" in
1304        --*)
1305                __gitcomp "
1306                        --all --tags --contains --abbrev= --candidates=
1307                        --exact-match --debug --long --match --always
1308                        "
1309                return
1310        esac
1311        __gitcomp_nl "$(__git_refs)"
1312}
1313
1314__git_diff_common_options="--stat --numstat --shortstat --summary
1315                        --patch-with-stat --name-only --name-status --color
1316                        --no-color --color-words --no-renames --check
1317                        --full-index --binary --abbrev --diff-filter=
1318                        --find-copies-harder
1319                        --text --ignore-space-at-eol --ignore-space-change
1320                        --ignore-all-space --exit-code --quiet --ext-diff
1321                        --no-ext-diff
1322                        --no-prefix --src-prefix= --dst-prefix=
1323                        --inter-hunk-context=
1324                        --patience
1325                        --raw
1326                        --dirstat --dirstat= --dirstat-by-file
1327                        --dirstat-by-file= --cumulative
1328"
1329
1330_git_diff ()
1331{
1332        __git_has_doubledash && return
1333
1334        case "$cur" in
1335        --*)
1336                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1337                        --base --ours --theirs --no-index
1338                        $__git_diff_common_options
1339                        "
1340                return
1341                ;;
1342        esac
1343        __git_complete_revlist_file
1344}
1345
1346__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
1347                        tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3
1348"
1349
1350_git_difftool ()
1351{
1352        __git_has_doubledash && return
1353
1354        case "$cur" in
1355        --tool=*)
1356                __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
1357                return
1358                ;;
1359        --*)
1360                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1361                        --base --ours --theirs
1362                        --no-renames --diff-filter= --find-copies-harder
1363                        --relative --ignore-submodules
1364                        --tool="
1365                return
1366                ;;
1367        esac
1368        __git_complete_file
1369}
1370
1371__git_fetch_options="
1372        --quiet --verbose --append --upload-pack --force --keep --depth=
1373        --tags --no-tags --all --prune --dry-run
1374"
1375
1376_git_fetch ()
1377{
1378        case "$cur" in
1379        --*)
1380                __gitcomp "$__git_fetch_options"
1381                return
1382                ;;
1383        esac
1384        __git_complete_remote_or_refspec
1385}
1386
1387_git_format_patch ()
1388{
1389        case "$cur" in
1390        --thread=*)
1391                __gitcomp "
1392                        deep shallow
1393                        " "" "${cur##--thread=}"
1394                return
1395                ;;
1396        --*)
1397                __gitcomp "
1398                        --stdout --attach --no-attach --thread --thread=
1399                        --output-directory
1400                        --numbered --start-number
1401                        --numbered-files
1402                        --keep-subject
1403                        --signoff --signature --no-signature
1404                        --in-reply-to= --cc=
1405                        --full-index --binary
1406                        --not --all
1407                        --cover-letter
1408                        --no-prefix --src-prefix= --dst-prefix=
1409                        --inline --suffix= --ignore-if-in-upstream
1410                        --subject-prefix=
1411                        "
1412                return
1413                ;;
1414        esac
1415        __git_complete_revlist
1416}
1417
1418_git_fsck ()
1419{
1420        case "$cur" in
1421        --*)
1422                __gitcomp "
1423                        --tags --root --unreachable --cache --no-reflogs --full
1424                        --strict --verbose --lost-found
1425                        "
1426                return
1427                ;;
1428        esac
1429        COMPREPLY=()
1430}
1431
1432_git_gc ()
1433{
1434        case "$cur" in
1435        --*)
1436                __gitcomp "--prune --aggressive"
1437                return
1438                ;;
1439        esac
1440        COMPREPLY=()
1441}
1442
1443_git_gitk ()
1444{
1445        _gitk
1446}
1447
1448__git_match_ctag() {
1449        awk "/^${1////\\/}/ { print \$1 }" "$2"
1450}
1451
1452_git_grep ()
1453{
1454        __git_has_doubledash && return
1455
1456        case "$cur" in
1457        --*)
1458                __gitcomp "
1459                        --cached
1460                        --text --ignore-case --word-regexp --invert-match
1461                        --full-name --line-number
1462                        --extended-regexp --basic-regexp --fixed-strings
1463                        --perl-regexp
1464                        --files-with-matches --name-only
1465                        --files-without-match
1466                        --max-depth
1467                        --count
1468                        --and --or --not --all-match
1469                        "
1470                return
1471                ;;
1472        esac
1473
1474        case "$cword,$prev" in
1475        2,*|*,-*)
1476                if test -r tags; then
1477                        __gitcomp_nl "$(__git_match_ctag "$cur" tags)"
1478                        return
1479                fi
1480                ;;
1481        esac
1482
1483        __gitcomp_nl "$(__git_refs)"
1484}
1485
1486_git_help ()
1487{
1488        case "$cur" in
1489        --*)
1490                __gitcomp "--all --info --man --web"
1491                return
1492                ;;
1493        esac
1494        __git_compute_all_commands
1495        __gitcomp "$__git_all_commands $(__git_aliases)
1496                attributes cli core-tutorial cvs-migration
1497                diffcore gitk glossary hooks ignore modules
1498                namespaces repository-layout tutorial tutorial-2
1499                workflows
1500                "
1501}
1502
1503_git_init ()
1504{
1505        case "$cur" in
1506        --shared=*)
1507                __gitcomp "
1508                        false true umask group all world everybody
1509                        " "" "${cur##--shared=}"
1510                return
1511                ;;
1512        --*)
1513                __gitcomp "--quiet --bare --template= --shared --shared="
1514                return
1515                ;;
1516        esac
1517        COMPREPLY=()
1518}
1519
1520_git_ls_files ()
1521{
1522        __git_has_doubledash && return
1523
1524        case "$cur" in
1525        --*)
1526                __gitcomp "--cached --deleted --modified --others --ignored
1527                        --stage --directory --no-empty-directory --unmerged
1528                        --killed --exclude= --exclude-from=
1529                        --exclude-per-directory= --exclude-standard
1530                        --error-unmatch --with-tree= --full-name
1531                        --abbrev --ignored --exclude-per-directory
1532                        "
1533                return
1534                ;;
1535        esac
1536        COMPREPLY=()
1537}
1538
1539_git_ls_remote ()
1540{
1541        __gitcomp_nl "$(__git_remotes)"
1542}
1543
1544_git_ls_tree ()
1545{
1546        __git_complete_file
1547}
1548
1549# Options that go well for log, shortlog and gitk
1550__git_log_common_options="
1551        --not --all
1552        --branches --tags --remotes
1553        --first-parent --merges --no-merges
1554        --max-count=
1555        --max-age= --since= --after=
1556        --min-age= --until= --before=
1557        --min-parents= --max-parents=
1558        --no-min-parents --no-max-parents
1559"
1560# Options that go well for log and gitk (not shortlog)
1561__git_log_gitk_options="
1562        --dense --sparse --full-history
1563        --simplify-merges --simplify-by-decoration
1564        --left-right --notes --no-notes
1565"
1566# Options that go well for log and shortlog (not gitk)
1567__git_log_shortlog_options="
1568        --author= --committer= --grep=
1569        --all-match
1570"
1571
1572__git_log_pretty_formats="oneline short medium full fuller email raw format:"
1573__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1574
1575_git_log ()
1576{
1577        __git_has_doubledash && return
1578
1579        local g="$(git rev-parse --git-dir 2>/dev/null)"
1580        local merge=""
1581        if [ -f "$g/MERGE_HEAD" ]; then
1582                merge="--merge"
1583        fi
1584        case "$cur" in
1585        --pretty=*|--format=*)
1586                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
1587                        " "" "${cur#*=}"
1588                return
1589                ;;
1590        --date=*)
1591                __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1592                return
1593                ;;
1594        --decorate=*)
1595                __gitcomp "long short" "" "${cur##--decorate=}"
1596                return
1597                ;;
1598        --*)
1599                __gitcomp "
1600                        $__git_log_common_options
1601                        $__git_log_shortlog_options
1602                        $__git_log_gitk_options
1603                        --root --topo-order --date-order --reverse
1604                        --follow --full-diff
1605                        --abbrev-commit --abbrev=
1606                        --relative-date --date=
1607                        --pretty= --format= --oneline
1608                        --cherry-pick
1609                        --graph
1610                        --decorate --decorate=
1611                        --walk-reflogs
1612                        --parents --children
1613                        $merge
1614                        $__git_diff_common_options
1615                        --pickaxe-all --pickaxe-regex
1616                        "
1617                return
1618                ;;
1619        esac
1620        __git_complete_revlist
1621}
1622
1623__git_merge_options="
1624        --no-commit --no-stat --log --no-log --squash --strategy
1625        --commit --stat --no-squash --ff --no-ff --ff-only
1626"
1627
1628_git_merge ()
1629{
1630        __git_complete_strategy && return
1631
1632        case "$cur" in
1633        --*)
1634                __gitcomp "$__git_merge_options"
1635                return
1636        esac
1637        __gitcomp_nl "$(__git_refs)"
1638}
1639
1640_git_mergetool ()
1641{
1642        case "$cur" in
1643        --tool=*)
1644                __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1645                return
1646                ;;
1647        --*)
1648                __gitcomp "--tool="
1649                return
1650                ;;
1651        esac
1652        COMPREPLY=()
1653}
1654
1655_git_merge_base ()
1656{
1657        __gitcomp_nl "$(__git_refs)"
1658}
1659
1660_git_mv ()
1661{
1662        case "$cur" in
1663        --*)
1664                __gitcomp "--dry-run"
1665                return
1666                ;;
1667        esac
1668        COMPREPLY=()
1669}
1670
1671_git_name_rev ()
1672{
1673        __gitcomp "--tags --all --stdin"
1674}
1675
1676_git_notes ()
1677{
1678        local subcommands='add append copy edit list prune remove show'
1679        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1680
1681        case "$subcommand,$cur" in
1682        ,--*)
1683                __gitcomp '--ref'
1684                ;;
1685        ,*)
1686                case "${words[cword-1]}" in
1687                --ref)
1688                        __gitcomp_nl "$(__git_refs)"
1689                        ;;
1690                *)
1691                        __gitcomp "$subcommands --ref"
1692                        ;;
1693                esac
1694                ;;
1695        add,--reuse-message=*|append,--reuse-message=*|\
1696        add,--reedit-message=*|append,--reedit-message=*)
1697                __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1698                ;;
1699        add,--*|append,--*)
1700                __gitcomp '--file= --message= --reedit-message=
1701                                --reuse-message='
1702                ;;
1703        copy,--*)
1704                __gitcomp '--stdin'
1705                ;;
1706        prune,--*)
1707                __gitcomp '--dry-run --verbose'
1708                ;;
1709        prune,*)
1710                ;;
1711        *)
1712                case "${words[cword-1]}" in
1713                -m|-F)
1714                        ;;
1715                *)
1716                        __gitcomp_nl "$(__git_refs)"
1717                        ;;
1718                esac
1719                ;;
1720        esac
1721}
1722
1723_git_pull ()
1724{
1725        __git_complete_strategy && return
1726
1727        case "$cur" in
1728        --*)
1729                __gitcomp "
1730                        --rebase --no-rebase
1731                        $__git_merge_options
1732                        $__git_fetch_options
1733                "
1734                return
1735                ;;
1736        esac
1737        __git_complete_remote_or_refspec
1738}
1739
1740_git_push ()
1741{
1742        case "$prev" in
1743        --repo)
1744                __gitcomp_nl "$(__git_remotes)"
1745                return
1746        esac
1747        case "$cur" in
1748        --repo=*)
1749                __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
1750                return
1751                ;;
1752        --*)
1753                __gitcomp "
1754                        --all --mirror --tags --dry-run --force --verbose
1755                        --receive-pack= --repo= --set-upstream
1756                "
1757                return
1758                ;;
1759        esac
1760        __git_complete_remote_or_refspec
1761}
1762
1763_git_rebase ()
1764{
1765        local dir="$(__gitdir)"
1766        if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1767                __gitcomp "--continue --skip --abort"
1768                return
1769        fi
1770        __git_complete_strategy && return
1771        case "$cur" in
1772        --whitespace=*)
1773                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1774                return
1775                ;;
1776        --*)
1777                __gitcomp "
1778                        --onto --merge --strategy --interactive
1779                        --preserve-merges --stat --no-stat
1780                        --committer-date-is-author-date --ignore-date
1781                        --ignore-whitespace --whitespace=
1782                        --autosquash
1783                        "
1784
1785                return
1786        esac
1787        __gitcomp_nl "$(__git_refs)"
1788}
1789
1790_git_reflog ()
1791{
1792        local subcommands="show delete expire"
1793        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1794
1795        if [ -z "$subcommand" ]; then
1796                __gitcomp "$subcommands"
1797        else
1798                __gitcomp_nl "$(__git_refs)"
1799        fi
1800}
1801
1802__git_send_email_confirm_options="always never auto cc compose"
1803__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1804
1805_git_send_email ()
1806{
1807        case "$cur" in
1808        --confirm=*)
1809                __gitcomp "
1810                        $__git_send_email_confirm_options
1811                        " "" "${cur##--confirm=}"
1812                return
1813                ;;
1814        --suppress-cc=*)
1815                __gitcomp "
1816                        $__git_send_email_suppresscc_options
1817                        " "" "${cur##--suppress-cc=}"
1818
1819                return
1820                ;;
1821        --smtp-encryption=*)
1822                __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
1823                return
1824                ;;
1825        --*)
1826                __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1827                        --compose --confirm= --dry-run --envelope-sender
1828                        --from --identity
1829                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1830                        --no-suppress-from --no-thread --quiet
1831                        --signed-off-by-cc --smtp-pass --smtp-server
1832                        --smtp-server-port --smtp-encryption= --smtp-user
1833                        --subject --suppress-cc= --suppress-from --thread --to
1834                        --validate --no-validate"
1835                return
1836                ;;
1837        esac
1838        COMPREPLY=()
1839}
1840
1841_git_stage ()
1842{
1843        _git_add
1844}
1845
1846__git_config_get_set_variables ()
1847{
1848        local prevword word config_file= c=$cword
1849        while [ $c -gt 1 ]; do
1850                word="${words[c]}"
1851                case "$word" in
1852                --global|--system|--file=*)
1853                        config_file="$word"
1854                        break
1855                        ;;
1856                -f|--file)
1857                        config_file="$word $prevword"
1858                        break
1859                        ;;
1860                esac
1861                prevword=$word
1862                c=$((--c))
1863        done
1864
1865        git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1866        while read -r line
1867        do
1868                case "$line" in
1869                *.*=*)
1870                        echo "${line/=*/}"
1871                        ;;
1872                esac
1873        done
1874}
1875
1876_git_config ()
1877{
1878        case "$prev" in
1879        branch.*.remote)
1880                __gitcomp_nl "$(__git_remotes)"
1881                return
1882                ;;
1883        branch.*.merge)
1884                __gitcomp_nl "$(__git_refs)"
1885                return
1886                ;;
1887        remote.*.fetch)
1888                local remote="${prev#remote.}"
1889                remote="${remote%.fetch}"
1890                if [ -z "$cur" ]; then
1891                        COMPREPLY=("refs/heads/")
1892                        return
1893                fi
1894                __gitcomp_nl "$(__git_refs_remotes "$remote")"
1895                return
1896                ;;
1897        remote.*.push)
1898                local remote="${prev#remote.}"
1899                remote="${remote%.push}"
1900                __gitcomp_nl "$(git --git-dir="$(__gitdir)" \
1901                        for-each-ref --format='%(refname):%(refname)' \
1902                        refs/heads)"
1903                return
1904                ;;
1905        pull.twohead|pull.octopus)
1906                __git_compute_merge_strategies
1907                __gitcomp "$__git_merge_strategies"
1908                return
1909                ;;
1910        color.branch|color.diff|color.interactive|\
1911        color.showbranch|color.status|color.ui)
1912                __gitcomp "always never auto"
1913                return
1914                ;;
1915        color.pager)
1916                __gitcomp "false true"
1917                return
1918                ;;
1919        color.*.*)
1920                __gitcomp "
1921                        normal black red green yellow blue magenta cyan white
1922                        bold dim ul blink reverse
1923                        "
1924                return
1925                ;;
1926        help.format)
1927                __gitcomp "man info web html"
1928                return
1929                ;;
1930        log.date)
1931                __gitcomp "$__git_log_date_formats"
1932                return
1933                ;;
1934        sendemail.aliasesfiletype)
1935                __gitcomp "mutt mailrc pine elm gnus"
1936                return
1937                ;;
1938        sendemail.confirm)
1939                __gitcomp "$__git_send_email_confirm_options"
1940                return
1941                ;;
1942        sendemail.suppresscc)
1943                __gitcomp "$__git_send_email_suppresscc_options"
1944                return
1945                ;;
1946        --get|--get-all|--unset|--unset-all)
1947                __gitcomp_nl "$(__git_config_get_set_variables)"
1948                return
1949                ;;
1950        *.*)
1951                COMPREPLY=()
1952                return
1953                ;;
1954        esac
1955        case "$cur" in
1956        --*)
1957                __gitcomp "
1958                        --global --system --file=
1959                        --list --replace-all
1960                        --get --get-all --get-regexp
1961                        --add --unset --unset-all
1962                        --remove-section --rename-section
1963                        "
1964                return
1965                ;;
1966        branch.*.*)
1967                local pfx="${cur%.*}." cur_="${cur##*.}"
1968                __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur_"
1969                return
1970                ;;
1971        branch.*)
1972                local pfx="${cur%.*}." cur_="${cur#*.}"
1973                __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
1974                return
1975                ;;
1976        guitool.*.*)
1977                local pfx="${cur%.*}." cur_="${cur##*.}"
1978                __gitcomp "
1979                        argprompt cmd confirm needsfile noconsole norescan
1980                        prompt revprompt revunmerged title
1981                        " "$pfx" "$cur_"
1982                return
1983                ;;
1984        difftool.*.*)
1985                local pfx="${cur%.*}." cur_="${cur##*.}"
1986                __gitcomp "cmd path" "$pfx" "$cur_"
1987                return
1988                ;;
1989        man.*.*)
1990                local pfx="${cur%.*}." cur_="${cur##*.}"
1991                __gitcomp "cmd path" "$pfx" "$cur_"
1992                return
1993                ;;
1994        mergetool.*.*)
1995                local pfx="${cur%.*}." cur_="${cur##*.}"
1996                __gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
1997                return
1998                ;;
1999        pager.*)
2000                local pfx="${cur%.*}." cur_="${cur#*.}"
2001                __git_compute_all_commands
2002                __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
2003                return
2004                ;;
2005        remote.*.*)
2006                local pfx="${cur%.*}." cur_="${cur##*.}"
2007                __gitcomp "
2008                        url proxy fetch push mirror skipDefaultUpdate
2009                        receivepack uploadpack tagopt pushurl
2010                        " "$pfx" "$cur_"
2011                return
2012                ;;
2013        remote.*)
2014                local pfx="${cur%.*}." cur_="${cur#*.}"
2015                __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
2016                return
2017                ;;
2018        url.*.*)
2019                local pfx="${cur%.*}." cur_="${cur##*.}"
2020                __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
2021                return
2022                ;;
2023        esac
2024        __gitcomp "
2025                add.ignoreErrors
2026                advice.commitBeforeMerge
2027                advice.detachedHead
2028                advice.implicitIdentity
2029                advice.pushNonFastForward
2030                advice.resolveConflict
2031                advice.statusHints
2032                alias.
2033                am.keepcr
2034                apply.ignorewhitespace
2035                apply.whitespace
2036                branch.autosetupmerge
2037                branch.autosetuprebase
2038                browser.
2039                clean.requireForce
2040                color.branch
2041                color.branch.current
2042                color.branch.local
2043                color.branch.plain
2044                color.branch.remote
2045                color.decorate.HEAD
2046                color.decorate.branch
2047                color.decorate.remoteBranch
2048                color.decorate.stash
2049                color.decorate.tag
2050                color.diff
2051                color.diff.commit
2052                color.diff.frag
2053                color.diff.func
2054                color.diff.meta
2055                color.diff.new
2056                color.diff.old
2057                color.diff.plain
2058                color.diff.whitespace
2059                color.grep
2060                color.grep.context
2061                color.grep.filename
2062                color.grep.function
2063                color.grep.linenumber
2064                color.grep.match
2065                color.grep.selected
2066                color.grep.separator
2067                color.interactive
2068                color.interactive.error
2069                color.interactive.header
2070                color.interactive.help
2071                color.interactive.prompt
2072                color.pager
2073                color.showbranch
2074                color.status
2075                color.status.added
2076                color.status.changed
2077                color.status.header
2078                color.status.nobranch
2079                color.status.untracked
2080                color.status.updated
2081                color.ui
2082                commit.status
2083                commit.template
2084                core.abbrev
2085                core.askpass
2086                core.attributesfile
2087                core.autocrlf
2088                core.bare
2089                core.bigFileThreshold
2090                core.compression
2091                core.createObject
2092                core.deltaBaseCacheLimit
2093                core.editor
2094                core.eol
2095                core.excludesfile
2096                core.fileMode
2097                core.fsyncobjectfiles
2098                core.gitProxy
2099                core.ignoreCygwinFSTricks
2100                core.ignoreStat
2101                core.ignorecase
2102                core.logAllRefUpdates
2103                core.loosecompression
2104                core.notesRef
2105                core.packedGitLimit
2106                core.packedGitWindowSize
2107                core.pager
2108                core.preferSymlinkRefs
2109                core.preloadindex
2110                core.quotepath
2111                core.repositoryFormatVersion
2112                core.safecrlf
2113                core.sharedRepository
2114                core.sparseCheckout
2115                core.symlinks
2116                core.trustctime
2117                core.warnAmbiguousRefs
2118                core.whitespace
2119                core.worktree
2120                diff.autorefreshindex
2121                diff.external
2122                diff.ignoreSubmodules
2123                diff.mnemonicprefix
2124                diff.noprefix
2125                diff.renameLimit
2126                diff.renames
2127                diff.suppressBlankEmpty
2128                diff.tool
2129                diff.wordRegex
2130                difftool.
2131                difftool.prompt
2132                fetch.recurseSubmodules
2133                fetch.unpackLimit
2134                format.attach
2135                format.cc
2136                format.headers
2137                format.numbered
2138                format.pretty
2139                format.signature
2140                format.signoff
2141                format.subjectprefix
2142                format.suffix
2143                format.thread
2144                format.to
2145                gc.
2146                gc.aggressiveWindow
2147                gc.auto
2148                gc.autopacklimit
2149                gc.packrefs
2150                gc.pruneexpire
2151                gc.reflogexpire
2152                gc.reflogexpireunreachable
2153                gc.rerereresolved
2154                gc.rerereunresolved
2155                gitcvs.allbinary
2156                gitcvs.commitmsgannotation
2157                gitcvs.dbTableNamePrefix
2158                gitcvs.dbdriver
2159                gitcvs.dbname
2160                gitcvs.dbpass
2161                gitcvs.dbuser
2162                gitcvs.enabled
2163                gitcvs.logfile
2164                gitcvs.usecrlfattr
2165                guitool.
2166                gui.blamehistoryctx
2167                gui.commitmsgwidth
2168                gui.copyblamethreshold
2169                gui.diffcontext
2170                gui.encoding
2171                gui.fastcopyblame
2172                gui.matchtrackingbranch
2173                gui.newbranchtemplate
2174                gui.pruneduringfetch
2175                gui.spellingdictionary
2176                gui.trustmtime
2177                help.autocorrect
2178                help.browser
2179                help.format
2180                http.lowSpeedLimit
2181                http.lowSpeedTime
2182                http.maxRequests
2183                http.minSessions
2184                http.noEPSV
2185                http.postBuffer
2186                http.proxy
2187                http.sslCAInfo
2188                http.sslCAPath
2189                http.sslCert
2190                http.sslCertPasswordProtected
2191                http.sslKey
2192                http.sslVerify
2193                http.useragent
2194                i18n.commitEncoding
2195                i18n.logOutputEncoding
2196                imap.authMethod
2197                imap.folder
2198                imap.host
2199                imap.pass
2200                imap.port
2201                imap.preformattedHTML
2202                imap.sslverify
2203                imap.tunnel
2204                imap.user
2205                init.templatedir
2206                instaweb.browser
2207                instaweb.httpd
2208                instaweb.local
2209                instaweb.modulepath
2210                instaweb.port
2211                interactive.singlekey
2212                log.date
2213                log.decorate
2214                log.showroot
2215                mailmap.file
2216                man.
2217                man.viewer
2218                merge.
2219                merge.conflictstyle
2220                merge.log
2221                merge.renameLimit
2222                merge.renormalize
2223                merge.stat
2224                merge.tool
2225                merge.verbosity
2226                mergetool.
2227                mergetool.keepBackup
2228                mergetool.keepTemporaries
2229                mergetool.prompt
2230                notes.displayRef
2231                notes.rewrite.
2232                notes.rewrite.amend
2233                notes.rewrite.rebase
2234                notes.rewriteMode
2235                notes.rewriteRef
2236                pack.compression
2237                pack.deltaCacheLimit
2238                pack.deltaCacheSize
2239                pack.depth
2240                pack.indexVersion
2241                pack.packSizeLimit
2242                pack.threads
2243                pack.window
2244                pack.windowMemory
2245                pager.
2246                pretty.
2247                pull.octopus
2248                pull.twohead
2249                push.default
2250                rebase.autosquash
2251                rebase.stat
2252                receive.autogc
2253                receive.denyCurrentBranch
2254                receive.denyDeleteCurrent
2255                receive.denyDeletes
2256                receive.denyNonFastForwards
2257                receive.fsckObjects
2258                receive.unpackLimit
2259                receive.updateserverinfo
2260                remotes.
2261                repack.usedeltabaseoffset
2262                rerere.autoupdate
2263                rerere.enabled
2264                sendemail.
2265                sendemail.aliasesfile
2266                sendemail.aliasfiletype
2267                sendemail.bcc
2268                sendemail.cc
2269                sendemail.cccmd
2270                sendemail.chainreplyto
2271                sendemail.confirm
2272                sendemail.envelopesender
2273                sendemail.from
2274                sendemail.identity
2275                sendemail.multiedit
2276                sendemail.signedoffbycc
2277                sendemail.smtpdomain
2278                sendemail.smtpencryption
2279                sendemail.smtppass
2280                sendemail.smtpserver
2281                sendemail.smtpserveroption
2282                sendemail.smtpserverport
2283                sendemail.smtpuser
2284                sendemail.suppresscc
2285                sendemail.suppressfrom
2286                sendemail.thread
2287                sendemail.to
2288                sendemail.validate
2289                showbranch.default
2290                status.relativePaths
2291                status.showUntrackedFiles
2292                status.submodulesummary
2293                submodule.
2294                tar.umask
2295                transfer.unpackLimit
2296                url.
2297                user.email
2298                user.name
2299                user.signingkey
2300                web.browser
2301                branch. remote.
2302        "
2303}
2304
2305_git_remote ()
2306{
2307        local subcommands="add rename rm show prune update set-head"
2308        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2309        if [ -z "$subcommand" ]; then
2310                __gitcomp "$subcommands"
2311                return
2312        fi
2313
2314        case "$subcommand" in
2315        rename|rm|show|prune)
2316                __gitcomp_nl "$(__git_remotes)"
2317                ;;
2318        update)
2319                local i c='' IFS=$'\n'
2320                for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
2321                        i="${i#remotes.}"
2322                        c="$c ${i/ */}"
2323                done
2324                __gitcomp "$c"
2325                ;;
2326        *)
2327                COMPREPLY=()
2328                ;;
2329        esac
2330}
2331
2332_git_replace ()
2333{
2334        __gitcomp_nl "$(__git_refs)"
2335}
2336
2337_git_reset ()
2338{
2339        __git_has_doubledash && return
2340
2341        case "$cur" in
2342        --*)
2343                __gitcomp "--merge --mixed --hard --soft --patch"
2344                return
2345                ;;
2346        esac
2347        __gitcomp_nl "$(__git_refs)"
2348}
2349
2350_git_revert ()
2351{
2352        case "$cur" in
2353        --*)
2354                __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
2355                return
2356                ;;
2357        esac
2358        __gitcomp_nl "$(__git_refs)"
2359}
2360
2361_git_rm ()
2362{
2363        __git_has_doubledash && return
2364
2365        case "$cur" in
2366        --*)
2367                __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
2368                return
2369                ;;
2370        esac
2371        COMPREPLY=()
2372}
2373
2374_git_shortlog ()
2375{
2376        __git_has_doubledash && return
2377
2378        case "$cur" in
2379        --*)
2380                __gitcomp "
2381                        $__git_log_common_options
2382                        $__git_log_shortlog_options
2383                        --numbered --summary
2384                        "
2385                return
2386                ;;
2387        esac
2388        __git_complete_revlist
2389}
2390
2391_git_show ()
2392{
2393        __git_has_doubledash && return
2394
2395        case "$cur" in
2396        --pretty=*|--format=*)
2397                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
2398                        " "" "${cur#*=}"
2399                return
2400                ;;
2401        --*)
2402                __gitcomp "--pretty= --format= --abbrev-commit --oneline
2403                        $__git_diff_common_options
2404                        "
2405                return
2406                ;;
2407        esac
2408        __git_complete_file
2409}
2410
2411_git_show_branch ()
2412{
2413        case "$cur" in
2414        --*)
2415                __gitcomp "
2416                        --all --remotes --topo-order --current --more=
2417                        --list --independent --merge-base --no-name
2418                        --color --no-color
2419                        --sha1-name --sparse --topics --reflog
2420                        "
2421                return
2422                ;;
2423        esac
2424        __git_complete_revlist
2425}
2426
2427_git_stash ()
2428{
2429        local save_opts='--keep-index --no-keep-index --quiet --patch'
2430        local subcommands='save list show apply clear drop pop create branch'
2431        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2432        if [ -z "$subcommand" ]; then
2433                case "$cur" in
2434                --*)
2435                        __gitcomp "$save_opts"
2436                        ;;
2437                *)
2438                        if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
2439                                __gitcomp "$subcommands"
2440                        else
2441                                COMPREPLY=()
2442                        fi
2443                        ;;
2444                esac
2445        else
2446                case "$subcommand,$cur" in
2447                save,--*)
2448                        __gitcomp "$save_opts"
2449                        ;;
2450                apply,--*|pop,--*)
2451                        __gitcomp "--index --quiet"
2452                        ;;
2453                show,--*|drop,--*|branch,--*)
2454                        COMPREPLY=()
2455                        ;;
2456                show,*|apply,*|drop,*|pop,*|branch,*)
2457                        __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
2458                                        | sed -n -e 's/:.*//p')"
2459                        ;;
2460                *)
2461                        COMPREPLY=()
2462                        ;;
2463                esac
2464        fi
2465}
2466
2467_git_submodule ()
2468{
2469        __git_has_doubledash && return
2470
2471        local subcommands="add status init update summary foreach sync"
2472        if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
2473                case "$cur" in
2474                --*)
2475                        __gitcomp "--quiet --cached"
2476                        ;;
2477                *)
2478                        __gitcomp "$subcommands"
2479                        ;;
2480                esac
2481                return
2482        fi
2483}
2484
2485_git_svn ()
2486{
2487        local subcommands="
2488                init fetch clone rebase dcommit log find-rev
2489                set-tree commit-diff info create-ignore propget
2490                proplist show-ignore show-externals branch tag blame
2491                migrate mkdirs reset gc
2492                "
2493        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2494        if [ -z "$subcommand" ]; then
2495                __gitcomp "$subcommands"
2496        else
2497                local remote_opts="--username= --config-dir= --no-auth-cache"
2498                local fc_opts="
2499                        --follow-parent --authors-file= --repack=
2500                        --no-metadata --use-svm-props --use-svnsync-props
2501                        --log-window-size= --no-checkout --quiet
2502                        --repack-flags --use-log-author --localtime
2503                        --ignore-paths= $remote_opts
2504                        "
2505                local init_opts="
2506                        --template= --shared= --trunk= --tags=
2507                        --branches= --stdlayout --minimize-url
2508                        --no-metadata --use-svm-props --use-svnsync-props
2509                        --rewrite-root= --prefix= --use-log-author
2510                        --add-author-from $remote_opts
2511                        "
2512                local cmt_opts="
2513                        --edit --rmdir --find-copies-harder --copy-similarity=
2514                        "
2515
2516                case "$subcommand,$cur" in
2517                fetch,--*)
2518                        __gitcomp "--revision= --fetch-all $fc_opts"
2519                        ;;
2520                clone,--*)
2521                        __gitcomp "--revision= $fc_opts $init_opts"
2522                        ;;
2523                init,--*)
2524                        __gitcomp "$init_opts"
2525                        ;;
2526                dcommit,--*)
2527                        __gitcomp "
2528                                --merge --strategy= --verbose --dry-run
2529                                --fetch-all --no-rebase --commit-url
2530                                --revision $cmt_opts $fc_opts
2531                                "
2532                        ;;
2533                set-tree,--*)
2534                        __gitcomp "--stdin $cmt_opts $fc_opts"
2535                        ;;
2536                create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
2537                show-externals,--*|mkdirs,--*)
2538                        __gitcomp "--revision="
2539                        ;;
2540                log,--*)
2541                        __gitcomp "
2542                                --limit= --revision= --verbose --incremental
2543                                --oneline --show-commit --non-recursive
2544                                --authors-file= --color
2545                                "
2546                        ;;
2547                rebase,--*)
2548                        __gitcomp "
2549                                --merge --verbose --strategy= --local
2550                                --fetch-all --dry-run $fc_opts
2551                                "
2552                        ;;
2553                commit-diff,--*)
2554                        __gitcomp "--message= --file= --revision= $cmt_opts"
2555                        ;;
2556                info,--*)
2557                        __gitcomp "--url"
2558                        ;;
2559                branch,--*)
2560                        __gitcomp "--dry-run --message --tag"
2561                        ;;
2562                tag,--*)
2563                        __gitcomp "--dry-run --message"
2564                        ;;
2565                blame,--*)
2566                        __gitcomp "--git-format"
2567                        ;;
2568                migrate,--*)
2569                        __gitcomp "
2570                                --config-dir= --ignore-paths= --minimize
2571                                --no-auth-cache --username=
2572                                "
2573                        ;;
2574                reset,--*)
2575                        __gitcomp "--revision= --parent"
2576                        ;;
2577                *)
2578                        COMPREPLY=()
2579                        ;;
2580                esac
2581        fi
2582}
2583
2584_git_tag ()
2585{
2586        local i c=1 f=0
2587        while [ $c -lt $cword ]; do
2588                i="${words[c]}"
2589                case "$i" in
2590                -d|-v)
2591                        __gitcomp_nl "$(__git_tags)"
2592                        return
2593                        ;;
2594                -f)
2595                        f=1
2596                        ;;
2597                esac
2598                c=$((++c))
2599        done
2600
2601        case "$prev" in
2602        -m|-F)
2603                COMPREPLY=()
2604                ;;
2605        -*|tag)
2606                if [ $f = 1 ]; then
2607                        __gitcomp_nl "$(__git_tags)"
2608                else
2609                        COMPREPLY=()
2610                fi
2611                ;;
2612        *)
2613                __gitcomp_nl "$(__git_refs)"
2614                ;;
2615        esac
2616}
2617
2618_git_whatchanged ()
2619{
2620        _git_log
2621}
2622
2623_git ()
2624{
2625        local i c=1 command __git_dir
2626
2627        if [[ -n ${ZSH_VERSION-} ]]; then
2628                emulate -L bash
2629                setopt KSH_TYPESET
2630
2631                # workaround zsh's bug that leaves 'words' as a special
2632                # variable in versions < 4.3.12
2633                typeset -h words
2634        fi
2635
2636        local cur words cword prev
2637        _get_comp_words_by_ref -n =: cur words cword prev
2638        while [ $c -lt $cword ]; do
2639                i="${words[c]}"
2640                case "$i" in
2641                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
2642                --bare)      __git_dir="." ;;
2643                --version|-p|--paginate) ;;
2644                --help) command="help"; break ;;
2645                *) command="$i"; break ;;
2646                esac
2647                c=$((++c))
2648        done
2649
2650        if [ -z "$command" ]; then
2651                case "$cur" in
2652                --*)   __gitcomp "
2653                        --paginate
2654                        --no-pager
2655                        --git-dir=
2656                        --bare
2657                        --version
2658                        --exec-path
2659                        --html-path
2660                        --work-tree=
2661                        --namespace=
2662                        --help
2663                        "
2664                        ;;
2665                *)     __git_compute_porcelain_commands
2666                       __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2667                esac
2668                return
2669        fi
2670
2671        local completion_func="_git_${command//-/_}"
2672        declare -f $completion_func >/dev/null && $completion_func && return
2673
2674        local expansion=$(__git_aliased_command "$command")
2675        if [ -n "$expansion" ]; then
2676                completion_func="_git_${expansion//-/_}"
2677                declare -f $completion_func >/dev/null && $completion_func
2678        fi
2679}
2680
2681_gitk ()
2682{
2683        if [[ -n ${ZSH_VERSION-} ]]; then
2684                emulate -L bash
2685                setopt KSH_TYPESET
2686
2687                # workaround zsh's bug that leaves 'words' as a special
2688                # variable in versions < 4.3.12
2689                typeset -h words
2690        fi
2691
2692        local cur words cword prev
2693        _get_comp_words_by_ref -n =: cur words cword prev
2694
2695        __git_has_doubledash && return
2696
2697        local g="$(__gitdir)"
2698        local merge=""
2699        if [ -f "$g/MERGE_HEAD" ]; then
2700                merge="--merge"
2701        fi
2702        case "$cur" in
2703        --*)
2704                __gitcomp "
2705                        $__git_log_common_options
2706                        $__git_log_gitk_options
2707                        $merge
2708                        "
2709                return
2710                ;;
2711        esac
2712        __git_complete_revlist
2713}
2714
2715complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \
2716        || complete -o default -o nospace -F _git git
2717complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \
2718        || complete -o default -o nospace -F _gitk gitk
2719
2720# The following are necessary only for Cygwin, and only are needed
2721# when the user has tab-completed the executable name and consequently
2722# included the '.exe' suffix.
2723#
2724if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
2725complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
2726        || complete -o default -o nospace -F _git git.exe
2727fi
2728
2729if [[ -n ${ZSH_VERSION-} ]]; then
2730        __git_shopt () {
2731                local option
2732                if [ $# -ne 2 ]; then
2733                        echo "USAGE: $0 (-q|-s|-u) <option>" >&2
2734                        return 1
2735                fi
2736                case "$2" in
2737                nullglob)
2738                        option="$2"
2739                        ;;
2740                *)
2741                        echo "$0: invalid option: $2" >&2
2742                        return 1
2743                esac
2744                case "$1" in
2745                -q)     setopt | grep -q "$option" ;;
2746                -u)     unsetopt "$option" ;;
2747                -s)     setopt "$option" ;;
2748                *)
2749                        echo "$0: invalid flag: $1" >&2
2750                        return 1
2751                esac
2752        }
2753else
2754        __git_shopt () {
2755                shopt "$@"
2756        }
2757fi