2fb88a8feff5dbfa368785e8872b42742b257eec
   1#
   2# bash completion support for core Git.
   3#
   4# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
   5# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
   6# Distributed under the GNU General Public License, version 2.0.
   7#
   8# The contained completion routines provide support for completing:
   9#
  10#    *) local and remote branch names
  11#    *) local and remote tag names
  12#    *) .git/remotes file names
  13#    *) git 'subcommands'
  14#    *) tree paths within 'ref:path/to/file' expressions
  15#    *) common --long-options
  16#
  17# To use these routines:
  18#
  19#    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
  20#    2) Added the following line to your .bashrc:
  21#        source ~/.git-completion.sh
  22#
  23#    3) You may want to make sure the git executable is available
  24#       in your PATH before this script is sourced, as some caching
  25#       is performed while the script loads.  If git isn't found
  26#       at source time then all lookups will be done on demand,
  27#       which may be slightly slower.
  28#
  29#    4) Consider changing your PS1 to also show the current branch:
  30#        PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
  31#
  32#       The argument to __git_ps1 will be displayed only if you
  33#       are currently in a git repository.  The %s token will be
  34#       the name of the current branch.
  35#
  36# To submit patches:
  37#
  38#    *) Read Documentation/SubmittingPatches
  39#    *) Send all patches to the current maintainer:
  40#
  41#       "Shawn O. Pearce" <spearce@spearce.org>
  42#
  43#    *) Always CC the Git mailing list:
  44#
  45#       git@vger.kernel.org
  46#
  47
  48case "$COMP_WORDBREAKS" in
  49*:*) : great ;;
  50*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
  51esac
  52
  53__gitdir ()
  54{
  55        if [ -z "$1" ]; then
  56                if [ -n "$__git_dir" ]; then
  57                        echo "$__git_dir"
  58                elif [ -d .git ]; then
  59                        echo .git
  60                else
  61                        git rev-parse --git-dir 2>/dev/null
  62                fi
  63        elif [ -d "$1/.git" ]; then
  64                echo "$1/.git"
  65        else
  66                echo "$1"
  67        fi
  68}
  69
  70__git_ps1 ()
  71{
  72        local g="$(git rev-parse --git-dir 2>/dev/null)"
  73        if [ -n "$g" ]; then
  74                local r
  75                local b
  76                if [ -d "$g/rebase-apply" ]
  77                then
  78                        if test -f "$g/rebase-apply/rebasing"
  79                        then
  80                                r="|REBASE"
  81                        elif test -f "$g/rebase-apply/applying"
  82                        then
  83                                r="|AM"
  84                        else
  85                                r="|AM/REBASE"
  86                        fi
  87                        b="$(git symbolic-ref HEAD 2>/dev/null)"
  88                elif [ -f "$g/rebase-merge/interactive" ]
  89                then
  90                        r="|REBASE-i"
  91                        b="$(cat "$g/rebase-merge/head-name")"
  92                elif [ -d "$g/rebase-merge" ]
  93                then
  94                        r="|REBASE-m"
  95                        b="$(cat "$g/rebase-merge/head-name")"
  96                elif [ -f "$g/MERGE_HEAD" ]
  97                then
  98                        r="|MERGING"
  99                        b="$(git symbolic-ref HEAD 2>/dev/null)"
 100                else
 101                        if [ -f "$g/BISECT_LOG" ]
 102                        then
 103                                r="|BISECTING"
 104                        fi
 105                        if ! b="$(git symbolic-ref HEAD 2>/dev/null)"
 106                        then
 107                                if ! b="$(git describe --exact-match HEAD 2>/dev/null)"
 108                                then
 109                                        b="$(cut -c1-7 "$g/HEAD")..."
 110                                fi
 111                        fi
 112                fi
 113
 114                if [ -n "$1" ]; then
 115                        printf "$1" "${b##refs/heads/}$r"
 116                else
 117                        printf " (%s)" "${b##refs/heads/}$r"
 118                fi
 119        fi
 120}
 121
 122__gitcomp_1 ()
 123{
 124        local c IFS=' '$'\t'$'\n'
 125        for c in $1; do
 126                case "$c$2" in
 127                --*=*) printf %s$'\n' "$c$2" ;;
 128                *.)    printf %s$'\n' "$c$2" ;;
 129                *)     printf %s$'\n' "$c$2 " ;;
 130                esac
 131        done
 132}
 133
 134__gitcomp ()
 135{
 136        local cur="${COMP_WORDS[COMP_CWORD]}"
 137        if [ $# -gt 2 ]; then
 138                cur="$3"
 139        fi
 140        case "$cur" in
 141        --*=)
 142                COMPREPLY=()
 143                ;;
 144        *)
 145                local IFS=$'\n'
 146                COMPREPLY=($(compgen -P "$2" \
 147                        -W "$(__gitcomp_1 "$1" "$4")" \
 148                        -- "$cur"))
 149                ;;
 150        esac
 151}
 152
 153__git_heads ()
 154{
 155        local cmd i is_hash=y dir="$(__gitdir "$1")"
 156        if [ -d "$dir" ]; then
 157                for i in $(git --git-dir="$dir" \
 158                        for-each-ref --format='%(refname)' \
 159                        refs/heads ); do
 160                        echo "${i#refs/heads/}"
 161                done
 162                return
 163        fi
 164        for i in $(git ls-remote "$1" 2>/dev/null); do
 165                case "$is_hash,$i" in
 166                y,*) is_hash=n ;;
 167                n,*^{}) is_hash=y ;;
 168                n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
 169                n,*) is_hash=y; echo "$i" ;;
 170                esac
 171        done
 172}
 173
 174__git_tags ()
 175{
 176        local cmd i is_hash=y dir="$(__gitdir "$1")"
 177        if [ -d "$dir" ]; then
 178                for i in $(git --git-dir="$dir" \
 179                        for-each-ref --format='%(refname)' \
 180                        refs/tags ); do
 181                        echo "${i#refs/tags/}"
 182                done
 183                return
 184        fi
 185        for i in $(git ls-remote "$1" 2>/dev/null); do
 186                case "$is_hash,$i" in
 187                y,*) is_hash=n ;;
 188                n,*^{}) is_hash=y ;;
 189                n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
 190                n,*) is_hash=y; echo "$i" ;;
 191                esac
 192        done
 193}
 194
 195__git_refs ()
 196{
 197        local cmd i is_hash=y dir="$(__gitdir "$1")"
 198        if [ -d "$dir" ]; then
 199                if [ -e "$dir/HEAD" ]; then echo HEAD; fi
 200                for i in $(git --git-dir="$dir" \
 201                        for-each-ref --format='%(refname)' \
 202                        refs/tags refs/heads refs/remotes); do
 203                        case "$i" in
 204                                refs/tags/*)    echo "${i#refs/tags/}" ;;
 205                                refs/heads/*)   echo "${i#refs/heads/}" ;;
 206                                refs/remotes/*) echo "${i#refs/remotes/}" ;;
 207                                *)              echo "$i" ;;
 208                        esac
 209                done
 210                return
 211        fi
 212        for i in $(git ls-remote "$dir" 2>/dev/null); do
 213                case "$is_hash,$i" in
 214                y,*) is_hash=n ;;
 215                n,*^{}) is_hash=y ;;
 216                n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
 217                n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
 218                n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
 219                n,*) is_hash=y; echo "$i" ;;
 220                esac
 221        done
 222}
 223
 224__git_refs2 ()
 225{
 226        local i
 227        for i in $(__git_refs "$1"); do
 228                echo "$i:$i"
 229        done
 230}
 231
 232__git_refs_remotes ()
 233{
 234        local cmd i is_hash=y
 235        for i in $(git ls-remote "$1" 2>/dev/null); do
 236                case "$is_hash,$i" in
 237                n,refs/heads/*)
 238                        is_hash=y
 239                        echo "$i:refs/remotes/$1/${i#refs/heads/}"
 240                        ;;
 241                y,*) is_hash=n ;;
 242                n,*^{}) is_hash=y ;;
 243                n,refs/tags/*) is_hash=y;;
 244                n,*) is_hash=y; ;;
 245                esac
 246        done
 247}
 248
 249__git_remotes ()
 250{
 251        local i ngoff IFS=$'\n' d="$(__gitdir)"
 252        shopt -q nullglob || ngoff=1
 253        shopt -s nullglob
 254        for i in "$d/remotes"/*; do
 255                echo ${i#$d/remotes/}
 256        done
 257        [ "$ngoff" ] && shopt -u nullglob
 258        for i in $(git --git-dir="$d" config --list); do
 259                case "$i" in
 260                remote.*.url=*)
 261                        i="${i#remote.}"
 262                        echo "${i/.url=*/}"
 263                        ;;
 264                esac
 265        done
 266}
 267
 268__git_merge_strategies ()
 269{
 270        if [ -n "$__git_merge_strategylist" ]; then
 271                echo "$__git_merge_strategylist"
 272                return
 273        fi
 274        sed -n "/^all_strategies='/{
 275                s/^all_strategies='//
 276                s/'//
 277                p
 278                q
 279                }" "$(git --exec-path)/git-merge"
 280}
 281__git_merge_strategylist=
 282__git_merge_strategylist="$(__git_merge_strategies 2>/dev/null)"
 283
 284__git_complete_file ()
 285{
 286        local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
 287        case "$cur" in
 288        ?*:*)
 289                ref="${cur%%:*}"
 290                cur="${cur#*:}"
 291                case "$cur" in
 292                ?*/*)
 293                        pfx="${cur%/*}"
 294                        cur="${cur##*/}"
 295                        ls="$ref:$pfx"
 296                        pfx="$pfx/"
 297                        ;;
 298                *)
 299                        ls="$ref"
 300                        ;;
 301            esac
 302
 303                case "$COMP_WORDBREAKS" in
 304                *:*) : great ;;
 305                *)   pfx="$ref:$pfx" ;;
 306                esac
 307
 308                local IFS=$'\n'
 309                COMPREPLY=($(compgen -P "$pfx" \
 310                        -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
 311                                | sed '/^100... blob /{
 312                                           s,^.*        ,,
 313                                           s,$, ,
 314                                       }
 315                                       /^120000 blob /{
 316                                           s,^.*        ,,
 317                                           s,$, ,
 318                                       }
 319                                       /^040000 tree /{
 320                                           s,^.*        ,,
 321                                           s,$,/,
 322                                       }
 323                                       s/^.*    //')" \
 324                        -- "$cur"))
 325                ;;
 326        *)
 327                __gitcomp "$(__git_refs)"
 328                ;;
 329        esac
 330}
 331
 332__git_complete_revlist ()
 333{
 334        local pfx cur="${COMP_WORDS[COMP_CWORD]}"
 335        case "$cur" in
 336        *...*)
 337                pfx="${cur%...*}..."
 338                cur="${cur#*...}"
 339                __gitcomp "$(__git_refs)" "$pfx" "$cur"
 340                ;;
 341        *..*)
 342                pfx="${cur%..*}.."
 343                cur="${cur#*..}"
 344                __gitcomp "$(__git_refs)" "$pfx" "$cur"
 345                ;;
 346        *)
 347                __gitcomp "$(__git_refs)"
 348                ;;
 349        esac
 350}
 351
 352__git_commands ()
 353{
 354        if [ -n "$__git_commandlist" ]; then
 355                echo "$__git_commandlist"
 356                return
 357        fi
 358        local i IFS=" "$'\n'
 359        for i in $(git help -a|egrep '^ ')
 360        do
 361                case $i in
 362                *--*)             : helper pattern;;
 363                applymbox)        : ask gittus;;
 364                applypatch)       : ask gittus;;
 365                archimport)       : import;;
 366                cat-file)         : plumbing;;
 367                check-attr)       : plumbing;;
 368                check-ref-format) : plumbing;;
 369                commit-tree)      : plumbing;;
 370                cvsexportcommit)  : export;;
 371                cvsimport)        : import;;
 372                cvsserver)        : daemon;;
 373                daemon)           : daemon;;
 374                diff-files)       : plumbing;;
 375                diff-index)       : plumbing;;
 376                diff-tree)        : plumbing;;
 377                fast-import)      : import;;
 378                fsck-objects)     : plumbing;;
 379                fetch-pack)       : plumbing;;
 380                fmt-merge-msg)    : plumbing;;
 381                for-each-ref)     : plumbing;;
 382                hash-object)      : plumbing;;
 383                http-*)           : transport;;
 384                index-pack)       : plumbing;;
 385                init-db)          : deprecated;;
 386                local-fetch)      : plumbing;;
 387                mailinfo)         : plumbing;;
 388                mailsplit)        : plumbing;;
 389                merge-*)          : plumbing;;
 390                mktree)           : plumbing;;
 391                mktag)            : plumbing;;
 392                pack-objects)     : plumbing;;
 393                pack-redundant)   : plumbing;;
 394                pack-refs)        : plumbing;;
 395                parse-remote)     : plumbing;;
 396                patch-id)         : plumbing;;
 397                peek-remote)      : plumbing;;
 398                prune)            : plumbing;;
 399                prune-packed)     : plumbing;;
 400                quiltimport)      : import;;
 401                read-tree)        : plumbing;;
 402                receive-pack)     : plumbing;;
 403                reflog)           : plumbing;;
 404                repo-config)      : deprecated;;
 405                rerere)           : plumbing;;
 406                rev-list)         : plumbing;;
 407                rev-parse)        : plumbing;;
 408                runstatus)        : plumbing;;
 409                sh-setup)         : internal;;
 410                shell)            : daemon;;
 411                send-pack)        : plumbing;;
 412                show-index)       : plumbing;;
 413                ssh-*)            : transport;;
 414                stripspace)       : plumbing;;
 415                symbolic-ref)     : plumbing;;
 416                tar-tree)         : deprecated;;
 417                unpack-file)      : plumbing;;
 418                unpack-objects)   : plumbing;;
 419                update-index)     : plumbing;;
 420                update-ref)       : plumbing;;
 421                update-server-info) : daemon;;
 422                upload-archive)   : plumbing;;
 423                upload-pack)      : plumbing;;
 424                write-tree)       : plumbing;;
 425                verify-tag)       : plumbing;;
 426                *) echo $i;;
 427                esac
 428        done
 429}
 430__git_commandlist=
 431__git_commandlist="$(__git_commands 2>/dev/null)"
 432
 433__git_aliases ()
 434{
 435        local i IFS=$'\n'
 436        for i in $(git --git-dir="$(__gitdir)" config --list); do
 437                case "$i" in
 438                alias.*)
 439                        i="${i#alias.}"
 440                        echo "${i/=*/}"
 441                        ;;
 442                esac
 443        done
 444}
 445
 446__git_aliased_command ()
 447{
 448        local word cmdline=$(git --git-dir="$(__gitdir)" \
 449                config --get "alias.$1")
 450        for word in $cmdline; do
 451                if [ "${word##-*}" ]; then
 452                        echo $word
 453                        return
 454                fi
 455        done
 456}
 457
 458__git_find_subcommand ()
 459{
 460        local word subcommand c=1
 461
 462        while [ $c -lt $COMP_CWORD ]; do
 463                word="${COMP_WORDS[c]}"
 464                for subcommand in $1; do
 465                        if [ "$subcommand" = "$word" ]; then
 466                                echo "$subcommand"
 467                                return
 468                        fi
 469                done
 470                c=$((++c))
 471        done
 472}
 473
 474__git_has_doubledash ()
 475{
 476        local c=1
 477        while [ $c -lt $COMP_CWORD ]; do
 478                if [ "--" = "${COMP_WORDS[c]}" ]; then
 479                        return 0
 480                fi
 481                c=$((++c))
 482        done
 483        return 1
 484}
 485
 486__git_whitespacelist="nowarn warn error error-all strip"
 487
 488_git_am ()
 489{
 490        local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
 491        if [ -d "$dir"/rebase-apply ]; then
 492                __gitcomp "--skip --resolved --abort"
 493                return
 494        fi
 495        case "$cur" in
 496        --whitespace=*)
 497                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 498                return
 499                ;;
 500        --*)
 501                __gitcomp "
 502                        --signoff --utf8 --binary --3way --interactive
 503                        --whitespace=
 504                        "
 505                return
 506        esac
 507        COMPREPLY=()
 508}
 509
 510_git_apply ()
 511{
 512        local cur="${COMP_WORDS[COMP_CWORD]}"
 513        case "$cur" in
 514        --whitespace=*)
 515                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 516                return
 517                ;;
 518        --*)
 519                __gitcomp "
 520                        --stat --numstat --summary --check --index
 521                        --cached --index-info --reverse --reject --unidiff-zero
 522                        --apply --no-add --exclude=
 523                        --whitespace= --inaccurate-eof --verbose
 524                        "
 525                return
 526        esac
 527        COMPREPLY=()
 528}
 529
 530_git_add ()
 531{
 532        __git_has_doubledash && return
 533
 534        local cur="${COMP_WORDS[COMP_CWORD]}"
 535        case "$cur" in
 536        --*)
 537                __gitcomp "
 538                        --interactive --refresh --patch --update --dry-run
 539                        --ignore-errors
 540                        "
 541                return
 542        esac
 543        COMPREPLY=()
 544}
 545
 546_git_bisect ()
 547{
 548        __git_has_doubledash && return
 549
 550        local subcommands="start bad good skip reset visualize replay log run"
 551        local subcommand="$(__git_find_subcommand "$subcommands")"
 552        if [ -z "$subcommand" ]; then
 553                __gitcomp "$subcommands"
 554                return
 555        fi
 556
 557        case "$subcommand" in
 558        bad|good|reset|skip)
 559                __gitcomp "$(__git_refs)"
 560                ;;
 561        *)
 562                COMPREPLY=()
 563                ;;
 564        esac
 565}
 566
 567_git_branch ()
 568{
 569        local i c=1 only_local_ref="n" has_r="n"
 570
 571        while [ $c -lt $COMP_CWORD ]; do
 572                i="${COMP_WORDS[c]}"
 573                case "$i" in
 574                -d|-m)  only_local_ref="y" ;;
 575                -r)     has_r="y" ;;
 576                esac
 577                c=$((++c))
 578        done
 579
 580        case "${COMP_WORDS[COMP_CWORD]}" in
 581        --*=*)  COMPREPLY=() ;;
 582        --*)
 583                __gitcomp "
 584                        --color --no-color --verbose --abbrev= --no-abbrev
 585                        --track --no-track --contains --merged --no-merged
 586                        "
 587                ;;
 588        *)
 589                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
 590                        __gitcomp "$(__git_heads)"
 591                else
 592                        __gitcomp "$(__git_refs)"
 593                fi
 594                ;;
 595        esac
 596}
 597
 598_git_bundle ()
 599{
 600        local mycword="$COMP_CWORD"
 601        case "${COMP_WORDS[0]}" in
 602        git)
 603                local cmd="${COMP_WORDS[2]}"
 604                mycword="$((mycword-1))"
 605                ;;
 606        git-bundle*)
 607                local cmd="${COMP_WORDS[1]}"
 608                ;;
 609        esac
 610        case "$mycword" in
 611        1)
 612                __gitcomp "create list-heads verify unbundle"
 613                ;;
 614        2)
 615                # looking for a file
 616                ;;
 617        *)
 618                case "$cmd" in
 619                        create)
 620                                __git_complete_revlist
 621                        ;;
 622                esac
 623                ;;
 624        esac
 625}
 626
 627_git_checkout ()
 628{
 629        __git_has_doubledash && return
 630
 631        __gitcomp "$(__git_refs)"
 632}
 633
 634_git_cherry ()
 635{
 636        __gitcomp "$(__git_refs)"
 637}
 638
 639_git_cherry_pick ()
 640{
 641        local cur="${COMP_WORDS[COMP_CWORD]}"
 642        case "$cur" in
 643        --*)
 644                __gitcomp "--edit --no-commit"
 645                ;;
 646        *)
 647                __gitcomp "$(__git_refs)"
 648                ;;
 649        esac
 650}
 651
 652_git_commit ()
 653{
 654        __git_has_doubledash && return
 655
 656        local cur="${COMP_WORDS[COMP_CWORD]}"
 657        case "$cur" in
 658        --*)
 659                __gitcomp "
 660                        --all --author= --signoff --verify --no-verify
 661                        --edit --amend --include --only
 662                        "
 663                return
 664        esac
 665        COMPREPLY=()
 666}
 667
 668_git_describe ()
 669{
 670        local cur="${COMP_WORDS[COMP_CWORD]}"
 671        case "$cur" in
 672        --*)
 673                __gitcomp "
 674                        --all --tags --contains --abbrev= --candidates=
 675                        --exact-match --debug --long --match --always
 676                        "
 677                return
 678        esac
 679        __gitcomp "$(__git_refs)"
 680}
 681
 682_git_diff ()
 683{
 684        __git_has_doubledash && return
 685
 686        local cur="${COMP_WORDS[COMP_CWORD]}"
 687        case "$cur" in
 688        --*)
 689                __gitcomp "--cached --stat --numstat --shortstat --summary
 690                        --patch-with-stat --name-only --name-status --color
 691                        --no-color --color-words --no-renames --check
 692                        --full-index --binary --abbrev --diff-filter
 693                        --find-copies-harder --pickaxe-all --pickaxe-regex
 694                        --text --ignore-space-at-eol --ignore-space-change
 695                        --ignore-all-space --exit-code --quiet --ext-diff
 696                        --no-ext-diff
 697                        --no-prefix --src-prefix= --dst-prefix=
 698                        --base --ours --theirs
 699                        "
 700                return
 701                ;;
 702        esac
 703        __git_complete_file
 704}
 705
 706_git_diff_tree ()
 707{
 708        __gitcomp "$(__git_refs)"
 709}
 710
 711_git_fetch ()
 712{
 713        local cur="${COMP_WORDS[COMP_CWORD]}"
 714
 715        case "${COMP_WORDS[0]},$COMP_CWORD" in
 716        git-fetch*,1)
 717                __gitcomp "$(__git_remotes)"
 718                ;;
 719        git,2)
 720                __gitcomp "$(__git_remotes)"
 721                ;;
 722        *)
 723                case "$cur" in
 724                *:*)
 725                        local pfx=""
 726                        case "$COMP_WORDBREAKS" in
 727                        *:*) : great ;;
 728                        *)   pfx="${cur%%:*}:" ;;
 729                        esac
 730                        __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
 731                        ;;
 732                *)
 733                        local remote
 734                        case "${COMP_WORDS[0]}" in
 735                        git-fetch) remote="${COMP_WORDS[1]}" ;;
 736                        git)       remote="${COMP_WORDS[2]}" ;;
 737                        esac
 738                        __gitcomp "$(__git_refs2 "$remote")"
 739                        ;;
 740                esac
 741                ;;
 742        esac
 743}
 744
 745_git_format_patch ()
 746{
 747        local cur="${COMP_WORDS[COMP_CWORD]}"
 748        case "$cur" in
 749        --*)
 750                __gitcomp "
 751                        --stdout --attach --thread
 752                        --output-directory
 753                        --numbered --start-number
 754                        --numbered-files
 755                        --keep-subject
 756                        --signoff
 757                        --in-reply-to=
 758                        --full-index --binary
 759                        --not --all
 760                        --cover-letter
 761                        --no-prefix --src-prefix= --dst-prefix=
 762                        "
 763                return
 764                ;;
 765        esac
 766        __git_complete_revlist
 767}
 768
 769_git_gc ()
 770{
 771        local cur="${COMP_WORDS[COMP_CWORD]}"
 772        case "$cur" in
 773        --*)
 774                __gitcomp "--prune --aggressive"
 775                return
 776                ;;
 777        esac
 778        COMPREPLY=()
 779}
 780
 781_git_ls_remote ()
 782{
 783        __gitcomp "$(__git_remotes)"
 784}
 785
 786_git_ls_tree ()
 787{
 788        __git_complete_file
 789}
 790
 791_git_log ()
 792{
 793        __git_has_doubledash && return
 794
 795        local cur="${COMP_WORDS[COMP_CWORD]}"
 796        case "$cur" in
 797        --pretty=*)
 798                __gitcomp "
 799                        oneline short medium full fuller email raw
 800                        " "" "${cur##--pretty=}"
 801                return
 802                ;;
 803        --date=*)
 804                __gitcomp "
 805                        relative iso8601 rfc2822 short local default
 806                " "" "${cur##--date=}"
 807                return
 808                ;;
 809        --*)
 810                __gitcomp "
 811                        --max-count= --max-age= --since= --after=
 812                        --min-age= --before= --until=
 813                        --root --topo-order --date-order --reverse
 814                        --no-merges --follow
 815                        --abbrev-commit --abbrev=
 816                        --relative-date --date=
 817                        --author= --committer= --grep=
 818                        --all-match
 819                        --pretty= --name-status --name-only --raw
 820                        --not --all
 821                        --left-right --cherry-pick
 822                        --graph
 823                        --stat --numstat --shortstat
 824                        --decorate --diff-filter=
 825                        --color-words --walk-reflogs
 826                        "
 827                return
 828                ;;
 829        esac
 830        __git_complete_revlist
 831}
 832
 833_git_merge ()
 834{
 835        local cur="${COMP_WORDS[COMP_CWORD]}"
 836        case "${COMP_WORDS[COMP_CWORD-1]}" in
 837        -s|--strategy)
 838                __gitcomp "$(__git_merge_strategies)"
 839                return
 840        esac
 841        case "$cur" in
 842        --strategy=*)
 843                __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
 844                return
 845                ;;
 846        --*)
 847                __gitcomp "
 848                        --no-commit --no-stat --log --no-log --squash --strategy
 849                        "
 850                return
 851        esac
 852        __gitcomp "$(__git_refs)"
 853}
 854
 855_git_merge_base ()
 856{
 857        __gitcomp "$(__git_refs)"
 858}
 859
 860_git_name_rev ()
 861{
 862        __gitcomp "--tags --all --stdin"
 863}
 864
 865_git_pull ()
 866{
 867        local cur="${COMP_WORDS[COMP_CWORD]}"
 868
 869        case "${COMP_WORDS[0]},$COMP_CWORD" in
 870        git-pull*,1)
 871                __gitcomp "$(__git_remotes)"
 872                ;;
 873        git,2)
 874                __gitcomp "$(__git_remotes)"
 875                ;;
 876        *)
 877                local remote
 878                case "${COMP_WORDS[0]}" in
 879                git-pull)  remote="${COMP_WORDS[1]}" ;;
 880                git)       remote="${COMP_WORDS[2]}" ;;
 881                esac
 882                __gitcomp "$(__git_refs "$remote")"
 883                ;;
 884        esac
 885}
 886
 887_git_push ()
 888{
 889        local cur="${COMP_WORDS[COMP_CWORD]}"
 890
 891        case "${COMP_WORDS[0]},$COMP_CWORD" in
 892        git-push*,1)
 893                __gitcomp "$(__git_remotes)"
 894                ;;
 895        git,2)
 896                __gitcomp "$(__git_remotes)"
 897                ;;
 898        *)
 899                case "$cur" in
 900                *:*)
 901                        local remote
 902                        case "${COMP_WORDS[0]}" in
 903                        git-push)  remote="${COMP_WORDS[1]}" ;;
 904                        git)       remote="${COMP_WORDS[2]}" ;;
 905                        esac
 906
 907                        local pfx=""
 908                        case "$COMP_WORDBREAKS" in
 909                        *:*) : great ;;
 910                        *)   pfx="${cur%%:*}:" ;;
 911                        esac
 912
 913                        __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
 914                        ;;
 915                +*)
 916                        __gitcomp "$(__git_refs)" + "${cur#+}"
 917                        ;;
 918                *)
 919                        __gitcomp "$(__git_refs)"
 920                        ;;
 921                esac
 922                ;;
 923        esac
 924}
 925
 926_git_rebase ()
 927{
 928        local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
 929        if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
 930                __gitcomp "--continue --skip --abort"
 931                return
 932        fi
 933        case "${COMP_WORDS[COMP_CWORD-1]}" in
 934        -s|--strategy)
 935                __gitcomp "$(__git_merge_strategies)"
 936                return
 937        esac
 938        case "$cur" in
 939        --strategy=*)
 940                __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
 941                return
 942                ;;
 943        --*)
 944                __gitcomp "--onto --merge --strategy --interactive"
 945                return
 946        esac
 947        __gitcomp "$(__git_refs)"
 948}
 949
 950_git_send_email ()
 951{
 952        local cur="${COMP_WORDS[COMP_CWORD]}"
 953        case "$cur" in
 954        --*)
 955                __gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
 956                        --dry-run --envelope-sender --from --identity
 957                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
 958                        --no-suppress-from --no-thread --quiet
 959                        --signed-off-by-cc --smtp-pass --smtp-server
 960                        --smtp-server-port --smtp-ssl --smtp-user --subject
 961                        --suppress-cc --suppress-from --thread --to"
 962                return
 963                ;;
 964        esac
 965        COMPREPLY=()
 966}
 967
 968_git_config ()
 969{
 970        local cur="${COMP_WORDS[COMP_CWORD]}"
 971        local prv="${COMP_WORDS[COMP_CWORD-1]}"
 972        case "$prv" in
 973        branch.*.remote)
 974                __gitcomp "$(__git_remotes)"
 975                return
 976                ;;
 977        branch.*.merge)
 978                __gitcomp "$(__git_refs)"
 979                return
 980                ;;
 981        remote.*.fetch)
 982                local remote="${prv#remote.}"
 983                remote="${remote%.fetch}"
 984                __gitcomp "$(__git_refs_remotes "$remote")"
 985                return
 986                ;;
 987        remote.*.push)
 988                local remote="${prv#remote.}"
 989                remote="${remote%.push}"
 990                __gitcomp "$(git --git-dir="$(__gitdir)" \
 991                        for-each-ref --format='%(refname):%(refname)' \
 992                        refs/heads)"
 993                return
 994                ;;
 995        pull.twohead|pull.octopus)
 996                __gitcomp "$(__git_merge_strategies)"
 997                return
 998                ;;
 999        color.branch|color.diff|color.status)
1000                __gitcomp "always never auto"
1001                return
1002                ;;
1003        color.*.*)
1004                __gitcomp "
1005                        black red green yellow blue magenta cyan white
1006                        bold dim ul blink reverse
1007                        "
1008                return
1009                ;;
1010        *.*)
1011                COMPREPLY=()
1012                return
1013                ;;
1014        esac
1015        case "$cur" in
1016        --*)
1017                __gitcomp "
1018                        --global --system --file=
1019                        --list --replace-all
1020                        --get --get-all --get-regexp
1021                        --add --unset --unset-all
1022                        --remove-section --rename-section
1023                        "
1024                return
1025                ;;
1026        branch.*.*)
1027                local pfx="${cur%.*}."
1028                cur="${cur##*.}"
1029                __gitcomp "remote merge" "$pfx" "$cur"
1030                return
1031                ;;
1032        branch.*)
1033                local pfx="${cur%.*}."
1034                cur="${cur#*.}"
1035                __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1036                return
1037                ;;
1038        remote.*.*)
1039                local pfx="${cur%.*}."
1040                cur="${cur##*.}"
1041                __gitcomp "
1042                        url fetch push skipDefaultUpdate
1043                        receivepack uploadpack tagopt
1044                        " "$pfx" "$cur"
1045                return
1046                ;;
1047        remote.*)
1048                local pfx="${cur%.*}."
1049                cur="${cur#*.}"
1050                __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1051                return
1052                ;;
1053        esac
1054        __gitcomp "
1055                apply.whitespace
1056                core.fileMode
1057                core.gitProxy
1058                core.ignoreStat
1059                core.preferSymlinkRefs
1060                core.logAllRefUpdates
1061                core.loosecompression
1062                core.repositoryFormatVersion
1063                core.sharedRepository
1064                core.warnAmbiguousRefs
1065                core.compression
1066                core.packedGitWindowSize
1067                core.packedGitLimit
1068                clean.requireForce
1069                color.branch
1070                color.branch.current
1071                color.branch.local
1072                color.branch.remote
1073                color.branch.plain
1074                color.diff
1075                color.diff.plain
1076                color.diff.meta
1077                color.diff.frag
1078                color.diff.old
1079                color.diff.new
1080                color.diff.commit
1081                color.diff.whitespace
1082                color.pager
1083                color.status
1084                color.status.header
1085                color.status.added
1086                color.status.changed
1087                color.status.untracked
1088                diff.renameLimit
1089                diff.renames
1090                fetch.unpackLimit
1091                format.headers
1092                format.subjectprefix
1093                gitcvs.enabled
1094                gitcvs.logfile
1095                gitcvs.allbinary
1096                gitcvs.dbname gitcvs.dbdriver gitcvs.dbuser gitcvs.dbpass
1097                gitcvs.dbtablenameprefix
1098                gc.packrefs
1099                gc.reflogexpire
1100                gc.reflogexpireunreachable
1101                gc.rerereresolved
1102                gc.rerereunresolved
1103                http.sslVerify
1104                http.sslCert
1105                http.sslKey
1106                http.sslCAInfo
1107                http.sslCAPath
1108                http.maxRequests
1109                http.lowSpeedLimit
1110                http.lowSpeedTime
1111                http.noEPSV
1112                i18n.commitEncoding
1113                i18n.logOutputEncoding
1114                log.showroot
1115                merge.tool
1116                merge.summary
1117                merge.verbosity
1118                pack.window
1119                pack.depth
1120                pack.windowMemory
1121                pack.compression
1122                pack.deltaCacheSize
1123                pack.deltaCacheLimit
1124                pull.octopus
1125                pull.twohead
1126                repack.useDeltaBaseOffset
1127                showbranch.default
1128                tar.umask
1129                transfer.unpackLimit
1130                receive.unpackLimit
1131                receive.denyNonFastForwards
1132                user.name
1133                user.email
1134                user.signingkey
1135                branch. remote.
1136        "
1137}
1138
1139_git_remote ()
1140{
1141        local subcommands="add rm show prune update"
1142        local subcommand="$(__git_find_subcommand "$subcommands")"
1143        if [ -z "$subcommand" ]; then
1144                __gitcomp "$subcommands"
1145                return
1146        fi
1147
1148        case "$subcommand" in
1149        rm|show|prune)
1150                __gitcomp "$(__git_remotes)"
1151                ;;
1152        update)
1153                local i c='' IFS=$'\n'
1154                for i in $(git --git-dir="$(__gitdir)" config --list); do
1155                        case "$i" in
1156                        remotes.*)
1157                                i="${i#remotes.}"
1158                                c="$c ${i/=*/}"
1159                                ;;
1160                        esac
1161                done
1162                __gitcomp "$c"
1163                ;;
1164        *)
1165                COMPREPLY=()
1166                ;;
1167        esac
1168}
1169
1170_git_reset ()
1171{
1172        __git_has_doubledash && return
1173
1174        local cur="${COMP_WORDS[COMP_CWORD]}"
1175        case "$cur" in
1176        --*)
1177                __gitcomp "--mixed --hard --soft"
1178                return
1179                ;;
1180        esac
1181        __gitcomp "$(__git_refs)"
1182}
1183
1184_git_rm ()
1185{
1186        __git_has_doubledash && return
1187
1188        local cur="${COMP_WORDS[COMP_CWORD]}"
1189        case "$cur" in
1190        --*)
1191                __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
1192                return
1193                ;;
1194        esac
1195        COMPREPLY=()
1196}
1197
1198_git_shortlog ()
1199{
1200        __git_has_doubledash && return
1201
1202        local cur="${COMP_WORDS[COMP_CWORD]}"
1203        case "$cur" in
1204        --*)
1205                __gitcomp "
1206                        --max-count= --max-age= --since= --after=
1207                        --min-age= --before= --until=
1208                        --no-merges
1209                        --author= --committer= --grep=
1210                        --all-match
1211                        --not --all
1212                        --numbered --summary
1213                        "
1214                return
1215                ;;
1216        esac
1217        __git_complete_revlist
1218}
1219
1220_git_show ()
1221{
1222        local cur="${COMP_WORDS[COMP_CWORD]}"
1223        case "$cur" in
1224        --pretty=*)
1225                __gitcomp "
1226                        oneline short medium full fuller email raw
1227                        " "" "${cur##--pretty=}"
1228                return
1229                ;;
1230        --*)
1231                __gitcomp "--pretty="
1232                return
1233                ;;
1234        esac
1235        __git_complete_file
1236}
1237
1238_git_show_branch ()
1239{
1240        local cur="${COMP_WORDS[COMP_CWORD]}"
1241        case "$cur" in
1242        --*)
1243                __gitcomp "
1244                        --all --remotes --topo-order --current --more=
1245                        --list --independent --merge-base --no-name
1246                        --sha1-name --topics --reflog
1247                        "
1248                return
1249                ;;
1250        esac
1251        __git_complete_revlist
1252}
1253
1254_git_stash ()
1255{
1256        local subcommands='save list show apply clear drop pop create'
1257        local subcommand="$(__git_find_subcommand "$subcommands")"
1258        if [ -z "$subcommand" ]; then
1259                __gitcomp "$subcommands"
1260        else
1261                local cur="${COMP_WORDS[COMP_CWORD]}"
1262                case "$subcommand,$cur" in
1263                save,--*)
1264                        __gitcomp "--keep-index"
1265                        ;;
1266                *)
1267                        COMPREPLY=()
1268                        ;;
1269                esac
1270        fi
1271}
1272
1273_git_submodule ()
1274{
1275        __git_has_doubledash && return
1276
1277        local subcommands="add status init update"
1278        if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1279                local cur="${COMP_WORDS[COMP_CWORD]}"
1280                case "$cur" in
1281                --*)
1282                        __gitcomp "--quiet --cached"
1283                        ;;
1284                *)
1285                        __gitcomp "$subcommands"
1286                        ;;
1287                esac
1288                return
1289        fi
1290}
1291
1292_git_svn ()
1293{
1294        local subcommands="
1295                init fetch clone rebase dcommit log find-rev
1296                set-tree commit-diff info create-ignore propget
1297                proplist show-ignore show-externals
1298                "
1299        local subcommand="$(__git_find_subcommand "$subcommands")"
1300        if [ -z "$subcommand" ]; then
1301                __gitcomp "$subcommands"
1302        else
1303                local remote_opts="--username= --config-dir= --no-auth-cache"
1304                local fc_opts="
1305                        --follow-parent --authors-file= --repack=
1306                        --no-metadata --use-svm-props --use-svnsync-props
1307                        --log-window-size= --no-checkout --quiet
1308                        --repack-flags --user-log-author $remote_opts
1309                        "
1310                local init_opts="
1311                        --template= --shared= --trunk= --tags=
1312                        --branches= --stdlayout --minimize-url
1313                        --no-metadata --use-svm-props --use-svnsync-props
1314                        --rewrite-root= $remote_opts
1315                        "
1316                local cmt_opts="
1317                        --edit --rmdir --find-copies-harder --copy-similarity=
1318                        "
1319
1320                local cur="${COMP_WORDS[COMP_CWORD]}"
1321                case "$subcommand,$cur" in
1322                fetch,--*)
1323                        __gitcomp "--revision= --fetch-all $fc_opts"
1324                        ;;
1325                clone,--*)
1326                        __gitcomp "--revision= $fc_opts $init_opts"
1327                        ;;
1328                init,--*)
1329                        __gitcomp "$init_opts"
1330                        ;;
1331                dcommit,--*)
1332                        __gitcomp "
1333                                --merge --strategy= --verbose --dry-run
1334                                --fetch-all --no-rebase $cmt_opts $fc_opts
1335                                "
1336                        ;;
1337                set-tree,--*)
1338                        __gitcomp "--stdin $cmt_opts $fc_opts"
1339                        ;;
1340                create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
1341                show-externals,--*)
1342                        __gitcomp "--revision="
1343                        ;;
1344                log,--*)
1345                        __gitcomp "
1346                                --limit= --revision= --verbose --incremental
1347                                --oneline --show-commit --non-recursive
1348                                --authors-file=
1349                                "
1350                        ;;
1351                rebase,--*)
1352                        __gitcomp "
1353                                --merge --verbose --strategy= --local
1354                                --fetch-all $fc_opts
1355                                "
1356                        ;;
1357                commit-diff,--*)
1358                        __gitcomp "--message= --file= --revision= $cmt_opts"
1359                        ;;
1360                info,--*)
1361                        __gitcomp "--url"
1362                        ;;
1363                *)
1364                        COMPREPLY=()
1365                        ;;
1366                esac
1367        fi
1368}
1369
1370_git_tag ()
1371{
1372        local i c=1 f=0
1373        while [ $c -lt $COMP_CWORD ]; do
1374                i="${COMP_WORDS[c]}"
1375                case "$i" in
1376                -d|-v)
1377                        __gitcomp "$(__git_tags)"
1378                        return
1379                        ;;
1380                -f)
1381                        f=1
1382                        ;;
1383                esac
1384                c=$((++c))
1385        done
1386
1387        case "${COMP_WORDS[COMP_CWORD-1]}" in
1388        -m|-F)
1389                COMPREPLY=()
1390                ;;
1391        -*|tag|git-tag)
1392                if [ $f = 1 ]; then
1393                        __gitcomp "$(__git_tags)"
1394                else
1395                        COMPREPLY=()
1396                fi
1397                ;;
1398        *)
1399                __gitcomp "$(__git_refs)"
1400                ;;
1401        esac
1402}
1403
1404_git ()
1405{
1406        local i c=1 command __git_dir
1407
1408        while [ $c -lt $COMP_CWORD ]; do
1409                i="${COMP_WORDS[c]}"
1410                case "$i" in
1411                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
1412                --bare)      __git_dir="." ;;
1413                --version|--help|-p|--paginate) ;;
1414                *) command="$i"; break ;;
1415                esac
1416                c=$((++c))
1417        done
1418
1419        if [ -z "$command" ]; then
1420                case "${COMP_WORDS[COMP_CWORD]}" in
1421                --*=*) COMPREPLY=() ;;
1422                --*)   __gitcomp "
1423                        --paginate
1424                        --no-pager
1425                        --git-dir=
1426                        --bare
1427                        --version
1428                        --exec-path
1429                        --work-tree=
1430                        --help
1431                        "
1432                        ;;
1433                *)     __gitcomp "$(__git_commands) $(__git_aliases)" ;;
1434                esac
1435                return
1436        fi
1437
1438        local expansion=$(__git_aliased_command "$command")
1439        [ "$expansion" ] && command="$expansion"
1440
1441        case "$command" in
1442        am)          _git_am ;;
1443        add)         _git_add ;;
1444        apply)       _git_apply ;;
1445        bisect)      _git_bisect ;;
1446        bundle)      _git_bundle ;;
1447        branch)      _git_branch ;;
1448        checkout)    _git_checkout ;;
1449        cherry)      _git_cherry ;;
1450        cherry-pick) _git_cherry_pick ;;
1451        commit)      _git_commit ;;
1452        config)      _git_config ;;
1453        describe)    _git_describe ;;
1454        diff)        _git_diff ;;
1455        fetch)       _git_fetch ;;
1456        format-patch) _git_format_patch ;;
1457        gc)          _git_gc ;;
1458        log)         _git_log ;;
1459        ls-remote)   _git_ls_remote ;;
1460        ls-tree)     _git_ls_tree ;;
1461        merge)       _git_merge;;
1462        merge-base)  _git_merge_base ;;
1463        name-rev)    _git_name_rev ;;
1464        pull)        _git_pull ;;
1465        push)        _git_push ;;
1466        rebase)      _git_rebase ;;
1467        remote)      _git_remote ;;
1468        reset)       _git_reset ;;
1469        rm)          _git_rm ;;
1470        send-email)  _git_send_email ;;
1471        shortlog)    _git_shortlog ;;
1472        show)        _git_show ;;
1473        show-branch) _git_show_branch ;;
1474        stash)       _git_stash ;;
1475        submodule)   _git_submodule ;;
1476        svn)         _git_svn ;;
1477        tag)         _git_tag ;;
1478        whatchanged) _git_log ;;
1479        *)           COMPREPLY=() ;;
1480        esac
1481}
1482
1483_gitk ()
1484{
1485        __git_has_doubledash && return
1486
1487        local cur="${COMP_WORDS[COMP_CWORD]}"
1488        local g="$(git rev-parse --git-dir 2>/dev/null)"
1489        local merge=""
1490        if [ -f $g/MERGE_HEAD ]; then
1491                merge="--merge"
1492        fi
1493        case "$cur" in
1494        --*)
1495                __gitcomp "--not --all $merge"
1496                return
1497                ;;
1498        esac
1499        __git_complete_revlist
1500}
1501
1502complete -o default -o nospace -F _git git
1503complete -o default -o nospace -F _gitk gitk
1504
1505# The following are necessary only for Cygwin, and only are needed
1506# when the user has tab-completed the executable name and consequently
1507# included the '.exe' suffix.
1508#
1509if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1510complete -o default -o nospace -F _git git.exe
1511fi