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