ec6eed673ae3837755aaede7b2ee5aa9dfedc16d
   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 IFS=$'\n' d="$(__gitdir)"
 647        test -d "$d/remotes" && ls -1 "$d/remotes"
 648        for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
 649                i="${i#remote.}"
 650                echo "${i/.url*/}"
 651        done
 652}
 653
 654__git_list_merge_strategies ()
 655{
 656        git merge -s help 2>&1 |
 657        sed -n -e '/[Aa]vailable strategies are: /,/^$/{
 658                s/\.$//
 659                s/.*://
 660                s/^[    ]*//
 661                s/[     ]*$//
 662                p
 663        }'
 664}
 665
 666__git_merge_strategies=
 667# 'git merge -s help' (and thus detection of the merge strategy
 668# list) fails, unfortunately, if run outside of any git working
 669# tree.  __git_merge_strategies is set to the empty string in
 670# that case, and the detection will be repeated the next time it
 671# is needed.
 672__git_compute_merge_strategies ()
 673{
 674        test -n "$__git_merge_strategies" ||
 675        __git_merge_strategies=$(__git_list_merge_strategies)
 676}
 677
 678__git_complete_revlist_file ()
 679{
 680        local pfx ls ref cur_="$cur"
 681        case "$cur_" in
 682        *..?*:*)
 683                return
 684                ;;
 685        ?*:*)
 686                ref="${cur_%%:*}"
 687                cur_="${cur_#*:}"
 688                case "$cur_" in
 689                ?*/*)
 690                        pfx="${cur_%/*}"
 691                        cur_="${cur_##*/}"
 692                        ls="$ref:$pfx"
 693                        pfx="$pfx/"
 694                        ;;
 695                *)
 696                        ls="$ref"
 697                        ;;
 698                esac
 699
 700                case "$COMP_WORDBREAKS" in
 701                *:*) : great ;;
 702                *)   pfx="$ref:$pfx" ;;
 703                esac
 704
 705                local IFS=$'\n'
 706                COMPREPLY=($(compgen -P "$pfx" \
 707                        -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
 708                                | sed '/^100... blob /{
 709                                           s,^.*        ,,
 710                                           s,$, ,
 711                                       }
 712                                       /^120000 blob /{
 713                                           s,^.*        ,,
 714                                           s,$, ,
 715                                       }
 716                                       /^040000 tree /{
 717                                           s,^.*        ,,
 718                                           s,$,/,
 719                                       }
 720                                       s/^.*    //')" \
 721                        -- "$cur_"))
 722                ;;
 723        *...*)
 724                pfx="${cur_%...*}..."
 725                cur_="${cur_#*...}"
 726                __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 727                ;;
 728        *..*)
 729                pfx="${cur_%..*}.."
 730                cur_="${cur_#*..}"
 731                __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 732                ;;
 733        *)
 734                __gitcomp_nl "$(__git_refs)"
 735                ;;
 736        esac
 737}
 738
 739
 740__git_complete_file ()
 741{
 742        __git_complete_revlist_file
 743}
 744
 745__git_complete_revlist ()
 746{
 747        __git_complete_revlist_file
 748}
 749
 750__git_complete_remote_or_refspec ()
 751{
 752        local cur_="$cur" cmd="${words[1]}"
 753        local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
 754        while [ $c -lt $cword ]; do
 755                i="${words[c]}"
 756                case "$i" in
 757                --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
 758                --all)
 759                        case "$cmd" in
 760                        push) no_complete_refspec=1 ;;
 761                        fetch)
 762                                COMPREPLY=()
 763                                return
 764                                ;;
 765                        *) ;;
 766                        esac
 767                        ;;
 768                -*) ;;
 769                *) remote="$i"; break ;;
 770                esac
 771                c=$((++c))
 772        done
 773        if [ -z "$remote" ]; then
 774                __gitcomp_nl "$(__git_remotes)"
 775                return
 776        fi
 777        if [ $no_complete_refspec = 1 ]; then
 778                COMPREPLY=()
 779                return
 780        fi
 781        [ "$remote" = "." ] && remote=
 782        case "$cur_" in
 783        *:*)
 784                case "$COMP_WORDBREAKS" in
 785                *:*) : great ;;
 786                *)   pfx="${cur_%%:*}:" ;;
 787                esac
 788                cur_="${cur_#*:}"
 789                lhs=0
 790                ;;
 791        +*)
 792                pfx="+"
 793                cur_="${cur_#+}"
 794                ;;
 795        esac
 796        case "$cmd" in
 797        fetch)
 798                if [ $lhs = 1 ]; then
 799                        __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
 800                else
 801                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 802                fi
 803                ;;
 804        pull)
 805                if [ $lhs = 1 ]; then
 806                        __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
 807                else
 808                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 809                fi
 810                ;;
 811        push)
 812                if [ $lhs = 1 ]; then
 813                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 814                else
 815                        __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
 816                fi
 817                ;;
 818        esac
 819}
 820
 821__git_complete_strategy ()
 822{
 823        __git_compute_merge_strategies
 824        case "$prev" in
 825        -s|--strategy)
 826                __gitcomp "$__git_merge_strategies"
 827                return 0
 828        esac
 829        case "$cur" in
 830        --strategy=*)
 831                __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
 832                return 0
 833                ;;
 834        esac
 835        return 1
 836}
 837
 838__git_list_all_commands ()
 839{
 840        local i IFS=" "$'\n'
 841        for i in $(git help -a|egrep '^  [a-zA-Z0-9]')
 842        do
 843                case $i in
 844                *--*)             : helper pattern;;
 845                *) echo $i;;
 846                esac
 847        done
 848}
 849
 850__git_all_commands=
 851__git_compute_all_commands ()
 852{
 853        test -n "$__git_all_commands" ||
 854        __git_all_commands=$(__git_list_all_commands)
 855}
 856
 857__git_list_porcelain_commands ()
 858{
 859        local i IFS=" "$'\n'
 860        __git_compute_all_commands
 861        for i in "help" $__git_all_commands
 862        do
 863                case $i in
 864                *--*)             : helper pattern;;
 865                applymbox)        : ask gittus;;
 866                applypatch)       : ask gittus;;
 867                archimport)       : import;;
 868                cat-file)         : plumbing;;
 869                check-attr)       : plumbing;;
 870                check-ref-format) : plumbing;;
 871                checkout-index)   : plumbing;;
 872                commit-tree)      : plumbing;;
 873                count-objects)    : infrequent;;
 874                cvsexportcommit)  : export;;
 875                cvsimport)        : import;;
 876                cvsserver)        : daemon;;
 877                daemon)           : daemon;;
 878                diff-files)       : plumbing;;
 879                diff-index)       : plumbing;;
 880                diff-tree)        : plumbing;;
 881                fast-import)      : import;;
 882                fast-export)      : export;;
 883                fsck-objects)     : plumbing;;
 884                fetch-pack)       : plumbing;;
 885                fmt-merge-msg)    : plumbing;;
 886                for-each-ref)     : plumbing;;
 887                hash-object)      : plumbing;;
 888                http-*)           : transport;;
 889                index-pack)       : plumbing;;
 890                init-db)          : deprecated;;
 891                local-fetch)      : plumbing;;
 892                lost-found)       : infrequent;;
 893                ls-files)         : plumbing;;
 894                ls-remote)        : plumbing;;
 895                ls-tree)          : plumbing;;
 896                mailinfo)         : plumbing;;
 897                mailsplit)        : plumbing;;
 898                merge-*)          : plumbing;;
 899                mktree)           : plumbing;;
 900                mktag)            : plumbing;;
 901                pack-objects)     : plumbing;;
 902                pack-redundant)   : plumbing;;
 903                pack-refs)        : plumbing;;
 904                parse-remote)     : plumbing;;
 905                patch-id)         : plumbing;;
 906                peek-remote)      : plumbing;;
 907                prune)            : plumbing;;
 908                prune-packed)     : plumbing;;
 909                quiltimport)      : import;;
 910                read-tree)        : plumbing;;
 911                receive-pack)     : plumbing;;
 912                remote-*)         : transport;;
 913                repo-config)      : deprecated;;
 914                rerere)           : plumbing;;
 915                rev-list)         : plumbing;;
 916                rev-parse)        : plumbing;;
 917                runstatus)        : plumbing;;
 918                sh-setup)         : internal;;
 919                shell)            : daemon;;
 920                show-ref)         : plumbing;;
 921                send-pack)        : plumbing;;
 922                show-index)       : plumbing;;
 923                ssh-*)            : transport;;
 924                stripspace)       : plumbing;;
 925                symbolic-ref)     : plumbing;;
 926                tar-tree)         : deprecated;;
 927                unpack-file)      : plumbing;;
 928                unpack-objects)   : plumbing;;
 929                update-index)     : plumbing;;
 930                update-ref)       : plumbing;;
 931                update-server-info) : daemon;;
 932                upload-archive)   : plumbing;;
 933                upload-pack)      : plumbing;;
 934                write-tree)       : plumbing;;
 935                var)              : infrequent;;
 936                verify-pack)      : infrequent;;
 937                verify-tag)       : plumbing;;
 938                *) echo $i;;
 939                esac
 940        done
 941}
 942
 943__git_porcelain_commands=
 944__git_compute_porcelain_commands ()
 945{
 946        __git_compute_all_commands
 947        test -n "$__git_porcelain_commands" ||
 948        __git_porcelain_commands=$(__git_list_porcelain_commands)
 949}
 950
 951__git_pretty_aliases ()
 952{
 953        local i IFS=$'\n'
 954        for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do
 955                case "$i" in
 956                pretty.*)
 957                        i="${i#pretty.}"
 958                        echo "${i/ */}"
 959                        ;;
 960                esac
 961        done
 962}
 963
 964__git_aliases ()
 965{
 966        local i IFS=$'\n'
 967        for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
 968                case "$i" in
 969                alias.*)
 970                        i="${i#alias.}"
 971                        echo "${i/ */}"
 972                        ;;
 973                esac
 974        done
 975}
 976
 977# __git_aliased_command requires 1 argument
 978__git_aliased_command ()
 979{
 980        local word cmdline=$(git --git-dir="$(__gitdir)" \
 981                config --get "alias.$1")
 982        for word in $cmdline; do
 983                case "$word" in
 984                \!gitk|gitk)
 985                        echo "gitk"
 986                        return
 987                        ;;
 988                \!*)    : shell command alias ;;
 989                -*)     : option ;;
 990                *=*)    : setting env ;;
 991                git)    : git itself ;;
 992                *)
 993                        echo "$word"
 994                        return
 995                esac
 996        done
 997}
 998
 999# __git_find_on_cmdline requires 1 argument
1000__git_find_on_cmdline ()
1001{
1002        local word subcommand c=1
1003        while [ $c -lt $cword ]; do
1004                word="${words[c]}"
1005                for subcommand in $1; do
1006                        if [ "$subcommand" = "$word" ]; then
1007                                echo "$subcommand"
1008                                return
1009                        fi
1010                done
1011                c=$((++c))
1012        done
1013}
1014
1015__git_has_doubledash ()
1016{
1017        local c=1
1018        while [ $c -lt $cword ]; do
1019                if [ "--" = "${words[c]}" ]; then
1020                        return 0
1021                fi
1022                c=$((++c))
1023        done
1024        return 1
1025}
1026
1027__git_whitespacelist="nowarn warn error error-all fix"
1028
1029_git_am ()
1030{
1031        local dir="$(__gitdir)"
1032        if [ -d "$dir"/rebase-apply ]; then
1033                __gitcomp "--skip --continue --resolved --abort"
1034                return
1035        fi
1036        case "$cur" in
1037        --whitespace=*)
1038                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1039                return
1040                ;;
1041        --*)
1042                __gitcomp "
1043                        --3way --committer-date-is-author-date --ignore-date
1044                        --ignore-whitespace --ignore-space-change
1045                        --interactive --keep --no-utf8 --signoff --utf8
1046                        --whitespace= --scissors
1047                        "
1048                return
1049        esac
1050        COMPREPLY=()
1051}
1052
1053_git_apply ()
1054{
1055        case "$cur" in
1056        --whitespace=*)
1057                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1058                return
1059                ;;
1060        --*)
1061                __gitcomp "
1062                        --stat --numstat --summary --check --index
1063                        --cached --index-info --reverse --reject --unidiff-zero
1064                        --apply --no-add --exclude=
1065                        --ignore-whitespace --ignore-space-change
1066                        --whitespace= --inaccurate-eof --verbose
1067                        "
1068                return
1069        esac
1070        COMPREPLY=()
1071}
1072
1073_git_add ()
1074{
1075        __git_has_doubledash && return
1076
1077        case "$cur" in
1078        --*)
1079                __gitcomp "
1080                        --interactive --refresh --patch --update --dry-run
1081                        --ignore-errors --intent-to-add
1082                        "
1083                return
1084        esac
1085        COMPREPLY=()
1086}
1087
1088_git_archive ()
1089{
1090        case "$cur" in
1091        --format=*)
1092                __gitcomp "$(git archive --list)" "" "${cur##--format=}"
1093                return
1094                ;;
1095        --remote=*)
1096                __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
1097                return
1098                ;;
1099        --*)
1100                __gitcomp "
1101                        --format= --list --verbose
1102                        --prefix= --remote= --exec=
1103                        "
1104                return
1105                ;;
1106        esac
1107        __git_complete_file
1108}
1109
1110_git_bisect ()
1111{
1112        __git_has_doubledash && return
1113
1114        local subcommands="start bad good skip reset visualize replay log run"
1115        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1116        if [ -z "$subcommand" ]; then
1117                if [ -f "$(__gitdir)"/BISECT_START ]; then
1118                        __gitcomp "$subcommands"
1119                else
1120                        __gitcomp "replay start"
1121                fi
1122                return
1123        fi
1124
1125        case "$subcommand" in
1126        bad|good|reset|skip|start)
1127                __gitcomp_nl "$(__git_refs)"
1128                ;;
1129        *)
1130                COMPREPLY=()
1131                ;;
1132        esac
1133}
1134
1135_git_branch ()
1136{
1137        local i c=1 only_local_ref="n" has_r="n"
1138
1139        while [ $c -lt $cword ]; do
1140                i="${words[c]}"
1141                case "$i" in
1142                -d|-m)  only_local_ref="y" ;;
1143                -r)     has_r="y" ;;
1144                esac
1145                c=$((++c))
1146        done
1147
1148        case "$cur" in
1149        --*)
1150                __gitcomp "
1151                        --color --no-color --verbose --abbrev= --no-abbrev
1152                        --track --no-track --contains --merged --no-merged
1153                        --set-upstream
1154                        "
1155                ;;
1156        *)
1157                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
1158                        __gitcomp_nl "$(__git_heads)"
1159                else
1160                        __gitcomp_nl "$(__git_refs)"
1161                fi
1162                ;;
1163        esac
1164}
1165
1166_git_bundle ()
1167{
1168        local cmd="${words[2]}"
1169        case "$cword" in
1170        2)
1171                __gitcomp "create list-heads verify unbundle"
1172                ;;
1173        3)
1174                # looking for a file
1175                ;;
1176        *)
1177                case "$cmd" in
1178                        create)
1179                                __git_complete_revlist
1180                        ;;
1181                esac
1182                ;;
1183        esac
1184}
1185
1186_git_checkout ()
1187{
1188        __git_has_doubledash && return
1189
1190        case "$cur" in
1191        --conflict=*)
1192                __gitcomp "diff3 merge" "" "${cur##--conflict=}"
1193                ;;
1194        --*)
1195                __gitcomp "
1196                        --quiet --ours --theirs --track --no-track --merge
1197                        --conflict= --orphan --patch
1198                        "
1199                ;;
1200        *)
1201                # check if --track, --no-track, or --no-guess was specified
1202                # if so, disable DWIM mode
1203                local flags="--track --no-track --no-guess" track=1
1204                if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
1205                        track=''
1206                fi
1207                __gitcomp_nl "$(__git_refs '' $track)"
1208                ;;
1209        esac
1210}
1211
1212_git_cherry ()
1213{
1214        __gitcomp "$(__git_refs)"
1215}
1216
1217_git_cherry_pick ()
1218{
1219        case "$cur" in
1220        --*)
1221                __gitcomp "--edit --no-commit"
1222                ;;
1223        *)
1224                __gitcomp_nl "$(__git_refs)"
1225                ;;
1226        esac
1227}
1228
1229_git_clean ()
1230{
1231        __git_has_doubledash && return
1232
1233        case "$cur" in
1234        --*)
1235                __gitcomp "--dry-run --quiet"
1236                return
1237                ;;
1238        esac
1239        COMPREPLY=()
1240}
1241
1242_git_clone ()
1243{
1244        case "$cur" in
1245        --*)
1246                __gitcomp "
1247                        --local
1248                        --no-hardlinks
1249                        --shared
1250                        --reference
1251                        --quiet
1252                        --no-checkout
1253                        --bare
1254                        --mirror
1255                        --origin
1256                        --upload-pack
1257                        --template=
1258                        --depth
1259                        "
1260                return
1261                ;;
1262        esac
1263        COMPREPLY=()
1264}
1265
1266_git_commit ()
1267{
1268        __git_has_doubledash && return
1269
1270        case "$cur" in
1271        --cleanup=*)
1272                __gitcomp "default strip verbatim whitespace
1273                        " "" "${cur##--cleanup=}"
1274                return
1275                ;;
1276        --reuse-message=*|--reedit-message=*|\
1277        --fixup=*|--squash=*)
1278                __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1279                return
1280                ;;
1281        --untracked-files=*)
1282                __gitcomp "all no normal" "" "${cur##--untracked-files=}"
1283                return
1284                ;;
1285        --*)
1286                __gitcomp "
1287                        --all --author= --signoff --verify --no-verify
1288                        --edit --amend --include --only --interactive
1289                        --dry-run --reuse-message= --reedit-message=
1290                        --reset-author --file= --message= --template=
1291                        --cleanup= --untracked-files --untracked-files=
1292                        --verbose --quiet --fixup= --squash=
1293                        "
1294                return
1295        esac
1296        COMPREPLY=()
1297}
1298
1299_git_describe ()
1300{
1301        case "$cur" in
1302        --*)
1303                __gitcomp "
1304                        --all --tags --contains --abbrev= --candidates=
1305                        --exact-match --debug --long --match --always
1306                        "
1307                return
1308        esac
1309        __gitcomp_nl "$(__git_refs)"
1310}
1311
1312__git_diff_common_options="--stat --numstat --shortstat --summary
1313                        --patch-with-stat --name-only --name-status --color
1314                        --no-color --color-words --no-renames --check
1315                        --full-index --binary --abbrev --diff-filter=
1316                        --find-copies-harder
1317                        --text --ignore-space-at-eol --ignore-space-change
1318                        --ignore-all-space --exit-code --quiet --ext-diff
1319                        --no-ext-diff
1320                        --no-prefix --src-prefix= --dst-prefix=
1321                        --inter-hunk-context=
1322                        --patience
1323                        --raw
1324                        --dirstat --dirstat= --dirstat-by-file
1325                        --dirstat-by-file= --cumulative
1326"
1327
1328_git_diff ()
1329{
1330        __git_has_doubledash && return
1331
1332        case "$cur" in
1333        --*)
1334                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1335                        --base --ours --theirs --no-index
1336                        $__git_diff_common_options
1337                        "
1338                return
1339                ;;
1340        esac
1341        __git_complete_revlist_file
1342}
1343
1344__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
1345                        tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3
1346"
1347
1348_git_difftool ()
1349{
1350        __git_has_doubledash && return
1351
1352        case "$cur" in
1353        --tool=*)
1354                __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
1355                return
1356                ;;
1357        --*)
1358                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1359                        --base --ours --theirs
1360                        --no-renames --diff-filter= --find-copies-harder
1361                        --relative --ignore-submodules
1362                        --tool="
1363                return
1364                ;;
1365        esac
1366        __git_complete_file
1367}
1368
1369__git_fetch_options="
1370        --quiet --verbose --append --upload-pack --force --keep --depth=
1371        --tags --no-tags --all --prune --dry-run
1372"
1373
1374_git_fetch ()
1375{
1376        case "$cur" in
1377        --*)
1378                __gitcomp "$__git_fetch_options"
1379                return
1380                ;;
1381        esac
1382        __git_complete_remote_or_refspec
1383}
1384
1385_git_format_patch ()
1386{
1387        case "$cur" in
1388        --thread=*)
1389                __gitcomp "
1390                        deep shallow
1391                        " "" "${cur##--thread=}"
1392                return
1393                ;;
1394        --*)
1395                __gitcomp "
1396                        --stdout --attach --no-attach --thread --thread=
1397                        --output-directory
1398                        --numbered --start-number
1399                        --numbered-files
1400                        --keep-subject
1401                        --signoff --signature --no-signature
1402                        --in-reply-to= --cc=
1403                        --full-index --binary
1404                        --not --all
1405                        --cover-letter
1406                        --no-prefix --src-prefix= --dst-prefix=
1407                        --inline --suffix= --ignore-if-in-upstream
1408                        --subject-prefix=
1409                        "
1410                return
1411                ;;
1412        esac
1413        __git_complete_revlist
1414}
1415
1416_git_fsck ()
1417{
1418        case "$cur" in
1419        --*)
1420                __gitcomp "
1421                        --tags --root --unreachable --cache --no-reflogs --full
1422                        --strict --verbose --lost-found
1423                        "
1424                return
1425                ;;
1426        esac
1427        COMPREPLY=()
1428}
1429
1430_git_gc ()
1431{
1432        case "$cur" in
1433        --*)
1434                __gitcomp "--prune --aggressive"
1435                return
1436                ;;
1437        esac
1438        COMPREPLY=()
1439}
1440
1441_git_gitk ()
1442{
1443        _gitk
1444}
1445
1446__git_match_ctag() {
1447        awk "/^${1////\\/}/ { print \$1 }" "$2"
1448}
1449
1450_git_grep ()
1451{
1452        __git_has_doubledash && return
1453
1454        case "$cur" in
1455        --*)
1456                __gitcomp "
1457                        --cached
1458                        --text --ignore-case --word-regexp --invert-match
1459                        --full-name --line-number
1460                        --extended-regexp --basic-regexp --fixed-strings
1461                        --perl-regexp
1462                        --files-with-matches --name-only
1463                        --files-without-match
1464                        --max-depth
1465                        --count
1466                        --and --or --not --all-match
1467                        "
1468                return
1469                ;;
1470        esac
1471
1472        case "$cword,$prev" in
1473        2,*|*,-*)
1474                if test -r tags; then
1475                        __gitcomp_nl "$(__git_match_ctag "$cur" tags)"
1476                        return
1477                fi
1478                ;;
1479        esac
1480
1481        __gitcomp_nl "$(__git_refs)"
1482}
1483
1484_git_help ()
1485{
1486        case "$cur" in
1487        --*)
1488                __gitcomp "--all --info --man --web"
1489                return
1490                ;;
1491        esac
1492        __git_compute_all_commands
1493        __gitcomp "$__git_all_commands $(__git_aliases)
1494                attributes cli core-tutorial cvs-migration
1495                diffcore gitk glossary hooks ignore modules
1496                namespaces repository-layout tutorial tutorial-2
1497                workflows
1498                "
1499}
1500
1501_git_init ()
1502{
1503        case "$cur" in
1504        --shared=*)
1505                __gitcomp "
1506                        false true umask group all world everybody
1507                        " "" "${cur##--shared=}"
1508                return
1509                ;;
1510        --*)
1511                __gitcomp "--quiet --bare --template= --shared --shared="
1512                return
1513                ;;
1514        esac
1515        COMPREPLY=()
1516}
1517
1518_git_ls_files ()
1519{
1520        __git_has_doubledash && return
1521
1522        case "$cur" in
1523        --*)
1524                __gitcomp "--cached --deleted --modified --others --ignored
1525                        --stage --directory --no-empty-directory --unmerged
1526                        --killed --exclude= --exclude-from=
1527                        --exclude-per-directory= --exclude-standard
1528                        --error-unmatch --with-tree= --full-name
1529                        --abbrev --ignored --exclude-per-directory
1530                        "
1531                return
1532                ;;
1533        esac
1534        COMPREPLY=()
1535}
1536
1537_git_ls_remote ()
1538{
1539        __gitcomp_nl "$(__git_remotes)"
1540}
1541
1542_git_ls_tree ()
1543{
1544        __git_complete_file
1545}
1546
1547# Options that go well for log, shortlog and gitk
1548__git_log_common_options="
1549        --not --all
1550        --branches --tags --remotes
1551        --first-parent --merges --no-merges
1552        --max-count=
1553        --max-age= --since= --after=
1554        --min-age= --until= --before=
1555        --min-parents= --max-parents=
1556        --no-min-parents --no-max-parents
1557"
1558# Options that go well for log and gitk (not shortlog)
1559__git_log_gitk_options="
1560        --dense --sparse --full-history
1561        --simplify-merges --simplify-by-decoration
1562        --left-right --notes --no-notes
1563"
1564# Options that go well for log and shortlog (not gitk)
1565__git_log_shortlog_options="
1566        --author= --committer= --grep=
1567        --all-match
1568"
1569
1570__git_log_pretty_formats="oneline short medium full fuller email raw format:"
1571__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1572
1573_git_log ()
1574{
1575        __git_has_doubledash && return
1576
1577        local g="$(git rev-parse --git-dir 2>/dev/null)"
1578        local merge=""
1579        if [ -f "$g/MERGE_HEAD" ]; then
1580                merge="--merge"
1581        fi
1582        case "$cur" in
1583        --pretty=*|--format=*)
1584                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
1585                        " "" "${cur#*=}"
1586                return
1587                ;;
1588        --date=*)
1589                __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1590                return
1591                ;;
1592        --decorate=*)
1593                __gitcomp "long short" "" "${cur##--decorate=}"
1594                return
1595                ;;
1596        --*)
1597                __gitcomp "
1598                        $__git_log_common_options
1599                        $__git_log_shortlog_options
1600                        $__git_log_gitk_options
1601                        --root --topo-order --date-order --reverse
1602                        --follow --full-diff
1603                        --abbrev-commit --abbrev=
1604                        --relative-date --date=
1605                        --pretty= --format= --oneline
1606                        --cherry-pick
1607                        --graph
1608                        --decorate --decorate=
1609                        --walk-reflogs
1610                        --parents --children
1611                        $merge
1612                        $__git_diff_common_options
1613                        --pickaxe-all --pickaxe-regex
1614                        "
1615                return
1616                ;;
1617        esac
1618        __git_complete_revlist
1619}
1620
1621__git_merge_options="
1622        --no-commit --no-stat --log --no-log --squash --strategy
1623        --commit --stat --no-squash --ff --no-ff --ff-only
1624"
1625
1626_git_merge ()
1627{
1628        __git_complete_strategy && return
1629
1630        case "$cur" in
1631        --*)
1632                __gitcomp "$__git_merge_options"
1633                return
1634        esac
1635        __gitcomp_nl "$(__git_refs)"
1636}
1637
1638_git_mergetool ()
1639{
1640        case "$cur" in
1641        --tool=*)
1642                __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1643                return
1644                ;;
1645        --*)
1646                __gitcomp "--tool="
1647                return
1648                ;;
1649        esac
1650        COMPREPLY=()
1651}
1652
1653_git_merge_base ()
1654{
1655        __gitcomp_nl "$(__git_refs)"
1656}
1657
1658_git_mv ()
1659{
1660        case "$cur" in
1661        --*)
1662                __gitcomp "--dry-run"
1663                return
1664                ;;
1665        esac
1666        COMPREPLY=()
1667}
1668
1669_git_name_rev ()
1670{
1671        __gitcomp "--tags --all --stdin"
1672}
1673
1674_git_notes ()
1675{
1676        local subcommands='add append copy edit list prune remove show'
1677        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1678
1679        case "$subcommand,$cur" in
1680        ,--*)
1681                __gitcomp '--ref'
1682                ;;
1683        ,*)
1684                case "${words[cword-1]}" in
1685                --ref)
1686                        __gitcomp_nl "$(__git_refs)"
1687                        ;;
1688                *)
1689                        __gitcomp "$subcommands --ref"
1690                        ;;
1691                esac
1692                ;;
1693        add,--reuse-message=*|append,--reuse-message=*|\
1694        add,--reedit-message=*|append,--reedit-message=*)
1695                __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1696                ;;
1697        add,--*|append,--*)
1698                __gitcomp '--file= --message= --reedit-message=
1699                                --reuse-message='
1700                ;;
1701        copy,--*)
1702                __gitcomp '--stdin'
1703                ;;
1704        prune,--*)
1705                __gitcomp '--dry-run --verbose'
1706                ;;
1707        prune,*)
1708                ;;
1709        *)
1710                case "${words[cword-1]}" in
1711                -m|-F)
1712                        ;;
1713                *)
1714                        __gitcomp_nl "$(__git_refs)"
1715                        ;;
1716                esac
1717                ;;
1718        esac
1719}
1720
1721_git_pull ()
1722{
1723        __git_complete_strategy && return
1724
1725        case "$cur" in
1726        --*)
1727                __gitcomp "
1728                        --rebase --no-rebase
1729                        $__git_merge_options
1730                        $__git_fetch_options
1731                "
1732                return
1733                ;;
1734        esac
1735        __git_complete_remote_or_refspec
1736}
1737
1738_git_push ()
1739{
1740        case "$prev" in
1741        --repo)
1742                __gitcomp_nl "$(__git_remotes)"
1743                return
1744        esac
1745        case "$cur" in
1746        --repo=*)
1747                __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
1748                return
1749                ;;
1750        --*)
1751                __gitcomp "
1752                        --all --mirror --tags --dry-run --force --verbose
1753                        --receive-pack= --repo= --set-upstream
1754                "
1755                return
1756                ;;
1757        esac
1758        __git_complete_remote_or_refspec
1759}
1760
1761_git_rebase ()
1762{
1763        local dir="$(__gitdir)"
1764        if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1765                __gitcomp "--continue --skip --abort"
1766                return
1767        fi
1768        __git_complete_strategy && return
1769        case "$cur" in
1770        --whitespace=*)
1771                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1772                return
1773                ;;
1774        --*)
1775                __gitcomp "
1776                        --onto --merge --strategy --interactive
1777                        --preserve-merges --stat --no-stat
1778                        --committer-date-is-author-date --ignore-date
1779                        --ignore-whitespace --whitespace=
1780                        --autosquash
1781                        "
1782
1783                return
1784        esac
1785        __gitcomp_nl "$(__git_refs)"
1786}
1787
1788_git_reflog ()
1789{
1790        local subcommands="show delete expire"
1791        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1792
1793        if [ -z "$subcommand" ]; then
1794                __gitcomp "$subcommands"
1795        else
1796                __gitcomp_nl "$(__git_refs)"
1797        fi
1798}
1799
1800__git_send_email_confirm_options="always never auto cc compose"
1801__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1802
1803_git_send_email ()
1804{
1805        case "$cur" in
1806        --confirm=*)
1807                __gitcomp "
1808                        $__git_send_email_confirm_options
1809                        " "" "${cur##--confirm=}"
1810                return
1811                ;;
1812        --suppress-cc=*)
1813                __gitcomp "
1814                        $__git_send_email_suppresscc_options
1815                        " "" "${cur##--suppress-cc=}"
1816
1817                return
1818                ;;
1819        --smtp-encryption=*)
1820                __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
1821                return
1822                ;;
1823        --*)
1824                __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1825                        --compose --confirm= --dry-run --envelope-sender
1826                        --from --identity
1827                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1828                        --no-suppress-from --no-thread --quiet
1829                        --signed-off-by-cc --smtp-pass --smtp-server
1830                        --smtp-server-port --smtp-encryption= --smtp-user
1831                        --subject --suppress-cc= --suppress-from --thread --to
1832                        --validate --no-validate"
1833                return
1834                ;;
1835        esac
1836        COMPREPLY=()
1837}
1838
1839_git_stage ()
1840{
1841        _git_add
1842}
1843
1844__git_config_get_set_variables ()
1845{
1846        local prevword word config_file= c=$cword
1847        while [ $c -gt 1 ]; do
1848                word="${words[c]}"
1849                case "$word" in
1850                --global|--system|--file=*)
1851                        config_file="$word"
1852                        break
1853                        ;;
1854                -f|--file)
1855                        config_file="$word $prevword"
1856                        break
1857                        ;;
1858                esac
1859                prevword=$word
1860                c=$((--c))
1861        done
1862
1863        git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1864        while read -r line
1865        do
1866                case "$line" in
1867                *.*=*)
1868                        echo "${line/=*/}"
1869                        ;;
1870                esac
1871        done
1872}
1873
1874_git_config ()
1875{
1876        case "$prev" in
1877        branch.*.remote)
1878                __gitcomp_nl "$(__git_remotes)"
1879                return
1880                ;;
1881        branch.*.merge)
1882                __gitcomp_nl "$(__git_refs)"
1883                return
1884                ;;
1885        remote.*.fetch)
1886                local remote="${prev#remote.}"
1887                remote="${remote%.fetch}"
1888                if [ -z "$cur" ]; then
1889                        COMPREPLY=("refs/heads/")
1890                        return
1891                fi
1892                __gitcomp_nl "$(__git_refs_remotes "$remote")"
1893                return
1894                ;;
1895        remote.*.push)
1896                local remote="${prev#remote.}"
1897                remote="${remote%.push}"
1898                __gitcomp_nl "$(git --git-dir="$(__gitdir)" \
1899                        for-each-ref --format='%(refname):%(refname)' \
1900                        refs/heads)"
1901                return
1902                ;;
1903        pull.twohead|pull.octopus)
1904                __git_compute_merge_strategies
1905                __gitcomp "$__git_merge_strategies"
1906                return
1907                ;;
1908        color.branch|color.diff|color.interactive|\
1909        color.showbranch|color.status|color.ui)
1910                __gitcomp "always never auto"
1911                return
1912                ;;
1913        color.pager)
1914                __gitcomp "false true"
1915                return
1916                ;;
1917        color.*.*)
1918                __gitcomp "
1919                        normal black red green yellow blue magenta cyan white
1920                        bold dim ul blink reverse
1921                        "
1922                return
1923                ;;
1924        help.format)
1925                __gitcomp "man info web html"
1926                return
1927                ;;
1928        log.date)
1929                __gitcomp "$__git_log_date_formats"
1930                return
1931                ;;
1932        sendemail.aliasesfiletype)
1933                __gitcomp "mutt mailrc pine elm gnus"
1934                return
1935                ;;
1936        sendemail.confirm)
1937                __gitcomp "$__git_send_email_confirm_options"
1938                return
1939                ;;
1940        sendemail.suppresscc)
1941                __gitcomp "$__git_send_email_suppresscc_options"
1942                return
1943                ;;
1944        --get|--get-all|--unset|--unset-all)
1945                __gitcomp_nl "$(__git_config_get_set_variables)"
1946                return
1947                ;;
1948        *.*)
1949                COMPREPLY=()
1950                return
1951                ;;
1952        esac
1953        case "$cur" in
1954        --*)
1955                __gitcomp "
1956                        --global --system --file=
1957                        --list --replace-all
1958                        --get --get-all --get-regexp
1959                        --add --unset --unset-all
1960                        --remove-section --rename-section
1961                        "
1962                return
1963                ;;
1964        branch.*.*)
1965                local pfx="${cur%.*}." cur_="${cur##*.}"
1966                __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur_"
1967                return
1968                ;;
1969        branch.*)
1970                local pfx="${cur%.*}." cur_="${cur#*.}"
1971                __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
1972                return
1973                ;;
1974        guitool.*.*)
1975                local pfx="${cur%.*}." cur_="${cur##*.}"
1976                __gitcomp "
1977                        argprompt cmd confirm needsfile noconsole norescan
1978                        prompt revprompt revunmerged title
1979                        " "$pfx" "$cur_"
1980                return
1981                ;;
1982        difftool.*.*)
1983                local pfx="${cur%.*}." cur_="${cur##*.}"
1984                __gitcomp "cmd path" "$pfx" "$cur_"
1985                return
1986                ;;
1987        man.*.*)
1988                local pfx="${cur%.*}." cur_="${cur##*.}"
1989                __gitcomp "cmd path" "$pfx" "$cur_"
1990                return
1991                ;;
1992        mergetool.*.*)
1993                local pfx="${cur%.*}." cur_="${cur##*.}"
1994                __gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
1995                return
1996                ;;
1997        pager.*)
1998                local pfx="${cur%.*}." cur_="${cur#*.}"
1999                __git_compute_all_commands
2000                __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
2001                return
2002                ;;
2003        remote.*.*)
2004                local pfx="${cur%.*}." cur_="${cur##*.}"
2005                __gitcomp "
2006                        url proxy fetch push mirror skipDefaultUpdate
2007                        receivepack uploadpack tagopt pushurl
2008                        " "$pfx" "$cur_"
2009                return
2010                ;;
2011        remote.*)
2012                local pfx="${cur%.*}." cur_="${cur#*.}"
2013                __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
2014                return
2015                ;;
2016        url.*.*)
2017                local pfx="${cur%.*}." cur_="${cur##*.}"
2018                __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
2019                return
2020                ;;
2021        esac
2022        __gitcomp "
2023                add.ignoreErrors
2024                advice.commitBeforeMerge
2025                advice.detachedHead
2026                advice.implicitIdentity
2027                advice.pushNonFastForward
2028                advice.resolveConflict
2029                advice.statusHints
2030                alias.
2031                am.keepcr
2032                apply.ignorewhitespace
2033                apply.whitespace
2034                branch.autosetupmerge
2035                branch.autosetuprebase
2036                browser.
2037                clean.requireForce
2038                color.branch
2039                color.branch.current
2040                color.branch.local
2041                color.branch.plain
2042                color.branch.remote
2043                color.decorate.HEAD
2044                color.decorate.branch
2045                color.decorate.remoteBranch
2046                color.decorate.stash
2047                color.decorate.tag
2048                color.diff
2049                color.diff.commit
2050                color.diff.frag
2051                color.diff.func
2052                color.diff.meta
2053                color.diff.new
2054                color.diff.old
2055                color.diff.plain
2056                color.diff.whitespace
2057                color.grep
2058                color.grep.context
2059                color.grep.filename
2060                color.grep.function
2061                color.grep.linenumber
2062                color.grep.match
2063                color.grep.selected
2064                color.grep.separator
2065                color.interactive
2066                color.interactive.error
2067                color.interactive.header
2068                color.interactive.help
2069                color.interactive.prompt
2070                color.pager
2071                color.showbranch
2072                color.status
2073                color.status.added
2074                color.status.changed
2075                color.status.header
2076                color.status.nobranch
2077                color.status.untracked
2078                color.status.updated
2079                color.ui
2080                commit.status
2081                commit.template
2082                core.abbrev
2083                core.askpass
2084                core.attributesfile
2085                core.autocrlf
2086                core.bare
2087                core.bigFileThreshold
2088                core.compression
2089                core.createObject
2090                core.deltaBaseCacheLimit
2091                core.editor
2092                core.eol
2093                core.excludesfile
2094                core.fileMode
2095                core.fsyncobjectfiles
2096                core.gitProxy
2097                core.ignoreCygwinFSTricks
2098                core.ignoreStat
2099                core.ignorecase
2100                core.logAllRefUpdates
2101                core.loosecompression
2102                core.notesRef
2103                core.packedGitLimit
2104                core.packedGitWindowSize
2105                core.pager
2106                core.preferSymlinkRefs
2107                core.preloadindex
2108                core.quotepath
2109                core.repositoryFormatVersion
2110                core.safecrlf
2111                core.sharedRepository
2112                core.sparseCheckout
2113                core.symlinks
2114                core.trustctime
2115                core.warnAmbiguousRefs
2116                core.whitespace
2117                core.worktree
2118                diff.autorefreshindex
2119                diff.external
2120                diff.ignoreSubmodules
2121                diff.mnemonicprefix
2122                diff.noprefix
2123                diff.renameLimit
2124                diff.renames
2125                diff.suppressBlankEmpty
2126                diff.tool
2127                diff.wordRegex
2128                difftool.
2129                difftool.prompt
2130                fetch.recurseSubmodules
2131                fetch.unpackLimit
2132                format.attach
2133                format.cc
2134                format.headers
2135                format.numbered
2136                format.pretty
2137                format.signature
2138                format.signoff
2139                format.subjectprefix
2140                format.suffix
2141                format.thread
2142                format.to
2143                gc.
2144                gc.aggressiveWindow
2145                gc.auto
2146                gc.autopacklimit
2147                gc.packrefs
2148                gc.pruneexpire
2149                gc.reflogexpire
2150                gc.reflogexpireunreachable
2151                gc.rerereresolved
2152                gc.rerereunresolved
2153                gitcvs.allbinary
2154                gitcvs.commitmsgannotation
2155                gitcvs.dbTableNamePrefix
2156                gitcvs.dbdriver
2157                gitcvs.dbname
2158                gitcvs.dbpass
2159                gitcvs.dbuser
2160                gitcvs.enabled
2161                gitcvs.logfile
2162                gitcvs.usecrlfattr
2163                guitool.
2164                gui.blamehistoryctx
2165                gui.commitmsgwidth
2166                gui.copyblamethreshold
2167                gui.diffcontext
2168                gui.encoding
2169                gui.fastcopyblame
2170                gui.matchtrackingbranch
2171                gui.newbranchtemplate
2172                gui.pruneduringfetch
2173                gui.spellingdictionary
2174                gui.trustmtime
2175                help.autocorrect
2176                help.browser
2177                help.format
2178                http.lowSpeedLimit
2179                http.lowSpeedTime
2180                http.maxRequests
2181                http.minSessions
2182                http.noEPSV
2183                http.postBuffer
2184                http.proxy
2185                http.sslCAInfo
2186                http.sslCAPath
2187                http.sslCert
2188                http.sslCertPasswordProtected
2189                http.sslKey
2190                http.sslVerify
2191                http.useragent
2192                i18n.commitEncoding
2193                i18n.logOutputEncoding
2194                imap.authMethod
2195                imap.folder
2196                imap.host
2197                imap.pass
2198                imap.port
2199                imap.preformattedHTML
2200                imap.sslverify
2201                imap.tunnel
2202                imap.user
2203                init.templatedir
2204                instaweb.browser
2205                instaweb.httpd
2206                instaweb.local
2207                instaweb.modulepath
2208                instaweb.port
2209                interactive.singlekey
2210                log.date
2211                log.decorate
2212                log.showroot
2213                mailmap.file
2214                man.
2215                man.viewer
2216                merge.
2217                merge.conflictstyle
2218                merge.log
2219                merge.renameLimit
2220                merge.renormalize
2221                merge.stat
2222                merge.tool
2223                merge.verbosity
2224                mergetool.
2225                mergetool.keepBackup
2226                mergetool.keepTemporaries
2227                mergetool.prompt
2228                notes.displayRef
2229                notes.rewrite.
2230                notes.rewrite.amend
2231                notes.rewrite.rebase
2232                notes.rewriteMode
2233                notes.rewriteRef
2234                pack.compression
2235                pack.deltaCacheLimit
2236                pack.deltaCacheSize
2237                pack.depth
2238                pack.indexVersion
2239                pack.packSizeLimit
2240                pack.threads
2241                pack.window
2242                pack.windowMemory
2243                pager.
2244                pretty.
2245                pull.octopus
2246                pull.twohead
2247                push.default
2248                rebase.autosquash
2249                rebase.stat
2250                receive.autogc
2251                receive.denyCurrentBranch
2252                receive.denyDeleteCurrent
2253                receive.denyDeletes
2254                receive.denyNonFastForwards
2255                receive.fsckObjects
2256                receive.unpackLimit
2257                receive.updateserverinfo
2258                remotes.
2259                repack.usedeltabaseoffset
2260                rerere.autoupdate
2261                rerere.enabled
2262                sendemail.
2263                sendemail.aliasesfile
2264                sendemail.aliasfiletype
2265                sendemail.bcc
2266                sendemail.cc
2267                sendemail.cccmd
2268                sendemail.chainreplyto
2269                sendemail.confirm
2270                sendemail.envelopesender
2271                sendemail.from
2272                sendemail.identity
2273                sendemail.multiedit
2274                sendemail.signedoffbycc
2275                sendemail.smtpdomain
2276                sendemail.smtpencryption
2277                sendemail.smtppass
2278                sendemail.smtpserver
2279                sendemail.smtpserveroption
2280                sendemail.smtpserverport
2281                sendemail.smtpuser
2282                sendemail.suppresscc
2283                sendemail.suppressfrom
2284                sendemail.thread
2285                sendemail.to
2286                sendemail.validate
2287                showbranch.default
2288                status.relativePaths
2289                status.showUntrackedFiles
2290                status.submodulesummary
2291                submodule.
2292                tar.umask
2293                transfer.unpackLimit
2294                url.
2295                user.email
2296                user.name
2297                user.signingkey
2298                web.browser
2299                branch. remote.
2300        "
2301}
2302
2303_git_remote ()
2304{
2305        local subcommands="add rename rm show prune update set-head"
2306        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2307        if [ -z "$subcommand" ]; then
2308                __gitcomp "$subcommands"
2309                return
2310        fi
2311
2312        case "$subcommand" in
2313        rename|rm|show|prune)
2314                __gitcomp_nl "$(__git_remotes)"
2315                ;;
2316        update)
2317                local i c='' IFS=$'\n'
2318                for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
2319                        i="${i#remotes.}"
2320                        c="$c ${i/ */}"
2321                done
2322                __gitcomp "$c"
2323                ;;
2324        *)
2325                COMPREPLY=()
2326                ;;
2327        esac
2328}
2329
2330_git_replace ()
2331{
2332        __gitcomp_nl "$(__git_refs)"
2333}
2334
2335_git_reset ()
2336{
2337        __git_has_doubledash && return
2338
2339        case "$cur" in
2340        --*)
2341                __gitcomp "--merge --mixed --hard --soft --patch"
2342                return
2343                ;;
2344        esac
2345        __gitcomp_nl "$(__git_refs)"
2346}
2347
2348_git_revert ()
2349{
2350        case "$cur" in
2351        --*)
2352                __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
2353                return
2354                ;;
2355        esac
2356        __gitcomp_nl "$(__git_refs)"
2357}
2358
2359_git_rm ()
2360{
2361        __git_has_doubledash && return
2362
2363        case "$cur" in
2364        --*)
2365                __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
2366                return
2367                ;;
2368        esac
2369        COMPREPLY=()
2370}
2371
2372_git_shortlog ()
2373{
2374        __git_has_doubledash && return
2375
2376        case "$cur" in
2377        --*)
2378                __gitcomp "
2379                        $__git_log_common_options
2380                        $__git_log_shortlog_options
2381                        --numbered --summary
2382                        "
2383                return
2384                ;;
2385        esac
2386        __git_complete_revlist
2387}
2388
2389_git_show ()
2390{
2391        __git_has_doubledash && return
2392
2393        case "$cur" in
2394        --pretty=*|--format=*)
2395                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
2396                        " "" "${cur#*=}"
2397                return
2398                ;;
2399        --*)
2400                __gitcomp "--pretty= --format= --abbrev-commit --oneline
2401                        $__git_diff_common_options
2402                        "
2403                return
2404                ;;
2405        esac
2406        __git_complete_file
2407}
2408
2409_git_show_branch ()
2410{
2411        case "$cur" in
2412        --*)
2413                __gitcomp "
2414                        --all --remotes --topo-order --current --more=
2415                        --list --independent --merge-base --no-name
2416                        --color --no-color
2417                        --sha1-name --sparse --topics --reflog
2418                        "
2419                return
2420                ;;
2421        esac
2422        __git_complete_revlist
2423}
2424
2425_git_stash ()
2426{
2427        local save_opts='--keep-index --no-keep-index --quiet --patch'
2428        local subcommands='save list show apply clear drop pop create branch'
2429        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2430        if [ -z "$subcommand" ]; then
2431                case "$cur" in
2432                --*)
2433                        __gitcomp "$save_opts"
2434                        ;;
2435                *)
2436                        if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
2437                                __gitcomp "$subcommands"
2438                        else
2439                                COMPREPLY=()
2440                        fi
2441                        ;;
2442                esac
2443        else
2444                case "$subcommand,$cur" in
2445                save,--*)
2446                        __gitcomp "$save_opts"
2447                        ;;
2448                apply,--*|pop,--*)
2449                        __gitcomp "--index --quiet"
2450                        ;;
2451                show,--*|drop,--*|branch,--*)
2452                        COMPREPLY=()
2453                        ;;
2454                show,*|apply,*|drop,*|pop,*|branch,*)
2455                        __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
2456                                        | sed -n -e 's/:.*//p')"
2457                        ;;
2458                *)
2459                        COMPREPLY=()
2460                        ;;
2461                esac
2462        fi
2463}
2464
2465_git_submodule ()
2466{
2467        __git_has_doubledash && return
2468
2469        local subcommands="add status init update summary foreach sync"
2470        if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
2471                case "$cur" in
2472                --*)
2473                        __gitcomp "--quiet --cached"
2474                        ;;
2475                *)
2476                        __gitcomp "$subcommands"
2477                        ;;
2478                esac
2479                return
2480        fi
2481}
2482
2483_git_svn ()
2484{
2485        local subcommands="
2486                init fetch clone rebase dcommit log find-rev
2487                set-tree commit-diff info create-ignore propget
2488                proplist show-ignore show-externals branch tag blame
2489                migrate mkdirs reset gc
2490                "
2491        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2492        if [ -z "$subcommand" ]; then
2493                __gitcomp "$subcommands"
2494        else
2495                local remote_opts="--username= --config-dir= --no-auth-cache"
2496                local fc_opts="
2497                        --follow-parent --authors-file= --repack=
2498                        --no-metadata --use-svm-props --use-svnsync-props
2499                        --log-window-size= --no-checkout --quiet
2500                        --repack-flags --use-log-author --localtime
2501                        --ignore-paths= $remote_opts
2502                        "
2503                local init_opts="
2504                        --template= --shared= --trunk= --tags=
2505                        --branches= --stdlayout --minimize-url
2506                        --no-metadata --use-svm-props --use-svnsync-props
2507                        --rewrite-root= --prefix= --use-log-author
2508                        --add-author-from $remote_opts
2509                        "
2510                local cmt_opts="
2511                        --edit --rmdir --find-copies-harder --copy-similarity=
2512                        "
2513
2514                case "$subcommand,$cur" in
2515                fetch,--*)
2516                        __gitcomp "--revision= --fetch-all $fc_opts"
2517                        ;;
2518                clone,--*)
2519                        __gitcomp "--revision= $fc_opts $init_opts"
2520                        ;;
2521                init,--*)
2522                        __gitcomp "$init_opts"
2523                        ;;
2524                dcommit,--*)
2525                        __gitcomp "
2526                                --merge --strategy= --verbose --dry-run
2527                                --fetch-all --no-rebase --commit-url
2528                                --revision $cmt_opts $fc_opts
2529                                "
2530                        ;;
2531                set-tree,--*)
2532                        __gitcomp "--stdin $cmt_opts $fc_opts"
2533                        ;;
2534                create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
2535                show-externals,--*|mkdirs,--*)
2536                        __gitcomp "--revision="
2537                        ;;
2538                log,--*)
2539                        __gitcomp "
2540                                --limit= --revision= --verbose --incremental
2541                                --oneline --show-commit --non-recursive
2542                                --authors-file= --color
2543                                "
2544                        ;;
2545                rebase,--*)
2546                        __gitcomp "
2547                                --merge --verbose --strategy= --local
2548                                --fetch-all --dry-run $fc_opts
2549                                "
2550                        ;;
2551                commit-diff,--*)
2552                        __gitcomp "--message= --file= --revision= $cmt_opts"
2553                        ;;
2554                info,--*)
2555                        __gitcomp "--url"
2556                        ;;
2557                branch,--*)
2558                        __gitcomp "--dry-run --message --tag"
2559                        ;;
2560                tag,--*)
2561                        __gitcomp "--dry-run --message"
2562                        ;;
2563                blame,--*)
2564                        __gitcomp "--git-format"
2565                        ;;
2566                migrate,--*)
2567                        __gitcomp "
2568                                --config-dir= --ignore-paths= --minimize
2569                                --no-auth-cache --username=
2570                                "
2571                        ;;
2572                reset,--*)
2573                        __gitcomp "--revision= --parent"
2574                        ;;
2575                *)
2576                        COMPREPLY=()
2577                        ;;
2578                esac
2579        fi
2580}
2581
2582_git_tag ()
2583{
2584        local i c=1 f=0
2585        while [ $c -lt $cword ]; do
2586                i="${words[c]}"
2587                case "$i" in
2588                -d|-v)
2589                        __gitcomp_nl "$(__git_tags)"
2590                        return
2591                        ;;
2592                -f)
2593                        f=1
2594                        ;;
2595                esac
2596                c=$((++c))
2597        done
2598
2599        case "$prev" in
2600        -m|-F)
2601                COMPREPLY=()
2602                ;;
2603        -*|tag)
2604                if [ $f = 1 ]; then
2605                        __gitcomp_nl "$(__git_tags)"
2606                else
2607                        COMPREPLY=()
2608                fi
2609                ;;
2610        *)
2611                __gitcomp_nl "$(__git_refs)"
2612                ;;
2613        esac
2614}
2615
2616_git_whatchanged ()
2617{
2618        _git_log
2619}
2620
2621_git ()
2622{
2623        local i c=1 command __git_dir
2624
2625        if [[ -n ${ZSH_VERSION-} ]]; then
2626                emulate -L bash
2627                setopt KSH_TYPESET
2628
2629                # workaround zsh's bug that leaves 'words' as a special
2630                # variable in versions < 4.3.12
2631                typeset -h words
2632
2633                # workaround zsh's bug that quotes spaces in the COMPREPLY
2634                # array if IFS doesn't contain spaces.
2635                typeset -h IFS
2636        fi
2637
2638        local cur words cword prev
2639        _get_comp_words_by_ref -n =: cur words cword prev
2640        while [ $c -lt $cword ]; do
2641                i="${words[c]}"
2642                case "$i" in
2643                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
2644                --bare)      __git_dir="." ;;
2645                --version|-p|--paginate) ;;
2646                --help) command="help"; break ;;
2647                *) command="$i"; break ;;
2648                esac
2649                c=$((++c))
2650        done
2651
2652        if [ -z "$command" ]; then
2653                case "$cur" in
2654                --*)   __gitcomp "
2655                        --paginate
2656                        --no-pager
2657                        --git-dir=
2658                        --bare
2659                        --version
2660                        --exec-path
2661                        --html-path
2662                        --work-tree=
2663                        --namespace=
2664                        --help
2665                        "
2666                        ;;
2667                *)     __git_compute_porcelain_commands
2668                       __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2669                esac
2670                return
2671        fi
2672
2673        local completion_func="_git_${command//-/_}"
2674        declare -f $completion_func >/dev/null && $completion_func && return
2675
2676        local expansion=$(__git_aliased_command "$command")
2677        if [ -n "$expansion" ]; then
2678                completion_func="_git_${expansion//-/_}"
2679                declare -f $completion_func >/dev/null && $completion_func
2680        fi
2681}
2682
2683_gitk ()
2684{
2685        if [[ -n ${ZSH_VERSION-} ]]; then
2686                emulate -L bash
2687                setopt KSH_TYPESET
2688
2689                # workaround zsh's bug that leaves 'words' as a special
2690                # variable in versions < 4.3.12
2691                typeset -h words
2692
2693                # workaround zsh's bug that quotes spaces in the COMPREPLY
2694                # array if IFS doesn't contain spaces.
2695                typeset -h IFS
2696        fi
2697
2698        local cur words cword prev
2699        _get_comp_words_by_ref -n =: cur words cword prev
2700
2701        __git_has_doubledash && return
2702
2703        local g="$(__gitdir)"
2704        local merge=""
2705        if [ -f "$g/MERGE_HEAD" ]; then
2706                merge="--merge"
2707        fi
2708        case "$cur" in
2709        --*)
2710                __gitcomp "
2711                        $__git_log_common_options
2712                        $__git_log_gitk_options
2713                        $merge
2714                        "
2715                return
2716                ;;
2717        esac
2718        __git_complete_revlist
2719}
2720
2721complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \
2722        || complete -o default -o nospace -F _git git
2723complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \
2724        || complete -o default -o nospace -F _gitk gitk
2725
2726# The following are necessary only for Cygwin, and only are needed
2727# when the user has tab-completed the executable name and consequently
2728# included the '.exe' suffix.
2729#
2730if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
2731complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
2732        || complete -o default -o nospace -F _git git.exe
2733fi