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