contrib / completion / git-completion.bashon commit Merge branch 'sp/maint-bash-completion-optim' (3df6499)
   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/../.dotest" ]
  77                then
  78                        if test -f "$g/../.dotest/rebasing"
  79                        then
  80                                r="|REBASE"
  81                        elif test -f "$g/../.dotest/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/.dotest-merge/interactive" ]
  89                then
  90                        r="|REBASE-i"
  91                        b="$(cat "$g/.dotest-merge/head-name")"
  92                elif [ -d "$g/.dotest-merge" ]
  93                then
  94                        r="|REBASE-m"
  95                        b="$(cat "$g/.dotest-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]}"
 491        if [ -d .dotest ]; then
 492                __gitcomp "--skip --resolved"
 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        __gitcomp "$(__git_refs)"
 630}
 631
 632_git_cherry ()
 633{
 634        __gitcomp "$(__git_refs)"
 635}
 636
 637_git_cherry_pick ()
 638{
 639        local cur="${COMP_WORDS[COMP_CWORD]}"
 640        case "$cur" in
 641        --*)
 642                __gitcomp "--edit --no-commit"
 643                ;;
 644        *)
 645                __gitcomp "$(__git_refs)"
 646                ;;
 647        esac
 648}
 649
 650_git_commit ()
 651{
 652        __git_has_doubledash && return
 653
 654        local cur="${COMP_WORDS[COMP_CWORD]}"
 655        case "$cur" in
 656        --*)
 657                __gitcomp "
 658                        --all --author= --signoff --verify --no-verify
 659                        --edit --amend --include --only
 660                        "
 661                return
 662        esac
 663        COMPREPLY=()
 664}
 665
 666_git_describe ()
 667{
 668        __gitcomp "$(__git_refs)"
 669}
 670
 671_git_diff ()
 672{
 673        __git_has_doubledash && return
 674
 675        local cur="${COMP_WORDS[COMP_CWORD]}"
 676        case "$cur" in
 677        --*)
 678                __gitcomp "--cached --stat --numstat --shortstat --summary
 679                        --patch-with-stat --name-only --name-status --color
 680                        --no-color --color-words --no-renames --check
 681                        --full-index --binary --abbrev --diff-filter
 682                        --find-copies-harder --pickaxe-all --pickaxe-regex
 683                        --text --ignore-space-at-eol --ignore-space-change
 684                        --ignore-all-space --exit-code --quiet --ext-diff
 685                        --no-ext-diff
 686                        --no-prefix --src-prefix= --dst-prefix=
 687                        --base --ours --theirs
 688                        "
 689                return
 690                ;;
 691        esac
 692        __git_complete_file
 693}
 694
 695_git_diff_tree ()
 696{
 697        __gitcomp "$(__git_refs)"
 698}
 699
 700_git_fetch ()
 701{
 702        local cur="${COMP_WORDS[COMP_CWORD]}"
 703
 704        case "${COMP_WORDS[0]},$COMP_CWORD" in
 705        git-fetch*,1)
 706                __gitcomp "$(__git_remotes)"
 707                ;;
 708        git,2)
 709                __gitcomp "$(__git_remotes)"
 710                ;;
 711        *)
 712                case "$cur" in
 713                *:*)
 714                        local pfx=""
 715                        case "$COMP_WORDBREAKS" in
 716                        *:*) : great ;;
 717                        *)   pfx="${cur%%:*}:" ;;
 718                        esac
 719                        __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
 720                        ;;
 721                *)
 722                        local remote
 723                        case "${COMP_WORDS[0]}" in
 724                        git-fetch) remote="${COMP_WORDS[1]}" ;;
 725                        git)       remote="${COMP_WORDS[2]}" ;;
 726                        esac
 727                        __gitcomp "$(__git_refs2 "$remote")"
 728                        ;;
 729                esac
 730                ;;
 731        esac
 732}
 733
 734_git_format_patch ()
 735{
 736        local cur="${COMP_WORDS[COMP_CWORD]}"
 737        case "$cur" in
 738        --*)
 739                __gitcomp "
 740                        --stdout --attach --thread
 741                        --output-directory
 742                        --numbered --start-number
 743                        --numbered-files
 744                        --keep-subject
 745                        --signoff
 746                        --in-reply-to=
 747                        --full-index --binary
 748                        --not --all
 749                        --cover-letter
 750                        --no-prefix --src-prefix= --dst-prefix=
 751                        "
 752                return
 753                ;;
 754        esac
 755        __git_complete_revlist
 756}
 757
 758_git_gc ()
 759{
 760        local cur="${COMP_WORDS[COMP_CWORD]}"
 761        case "$cur" in
 762        --*)
 763                __gitcomp "--prune --aggressive"
 764                return
 765                ;;
 766        esac
 767        COMPREPLY=()
 768}
 769
 770_git_ls_remote ()
 771{
 772        __gitcomp "$(__git_remotes)"
 773}
 774
 775_git_ls_tree ()
 776{
 777        __git_complete_file
 778}
 779
 780_git_log ()
 781{
 782        __git_has_doubledash && return
 783
 784        local cur="${COMP_WORDS[COMP_CWORD]}"
 785        case "$cur" in
 786        --pretty=*)
 787                __gitcomp "
 788                        oneline short medium full fuller email raw
 789                        " "" "${cur##--pretty=}"
 790                return
 791                ;;
 792        --date=*)
 793                __gitcomp "
 794                        relative iso8601 rfc2822 short local default
 795                " "" "${cur##--date=}"
 796                return
 797                ;;
 798        --*)
 799                __gitcomp "
 800                        --max-count= --max-age= --since= --after=
 801                        --min-age= --before= --until=
 802                        --root --topo-order --date-order --reverse
 803                        --no-merges --follow
 804                        --abbrev-commit --abbrev=
 805                        --relative-date --date=
 806                        --author= --committer= --grep=
 807                        --all-match
 808                        --pretty= --name-status --name-only --raw
 809                        --not --all
 810                        --left-right --cherry-pick
 811                        --graph
 812                        --stat --numstat --shortstat
 813                        --decorate --diff-filter=
 814                        --color-words --walk-reflogs
 815                        "
 816                return
 817                ;;
 818        esac
 819        __git_complete_revlist
 820}
 821
 822_git_merge ()
 823{
 824        local cur="${COMP_WORDS[COMP_CWORD]}"
 825        case "${COMP_WORDS[COMP_CWORD-1]}" in
 826        -s|--strategy)
 827                __gitcomp "$(__git_merge_strategies)"
 828                return
 829        esac
 830        case "$cur" in
 831        --strategy=*)
 832                __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
 833                return
 834                ;;
 835        --*)
 836                __gitcomp "
 837                        --no-commit --no-stat --log --no-log --squash --strategy
 838                        "
 839                return
 840        esac
 841        __gitcomp "$(__git_refs)"
 842}
 843
 844_git_merge_base ()
 845{
 846        __gitcomp "$(__git_refs)"
 847}
 848
 849_git_name_rev ()
 850{
 851        __gitcomp "--tags --all --stdin"
 852}
 853
 854_git_pull ()
 855{
 856        local cur="${COMP_WORDS[COMP_CWORD]}"
 857
 858        case "${COMP_WORDS[0]},$COMP_CWORD" in
 859        git-pull*,1)
 860                __gitcomp "$(__git_remotes)"
 861                ;;
 862        git,2)
 863                __gitcomp "$(__git_remotes)"
 864                ;;
 865        *)
 866                local remote
 867                case "${COMP_WORDS[0]}" in
 868                git-pull)  remote="${COMP_WORDS[1]}" ;;
 869                git)       remote="${COMP_WORDS[2]}" ;;
 870                esac
 871                __gitcomp "$(__git_refs "$remote")"
 872                ;;
 873        esac
 874}
 875
 876_git_push ()
 877{
 878        local cur="${COMP_WORDS[COMP_CWORD]}"
 879
 880        case "${COMP_WORDS[0]},$COMP_CWORD" in
 881        git-push*,1)
 882                __gitcomp "$(__git_remotes)"
 883                ;;
 884        git,2)
 885                __gitcomp "$(__git_remotes)"
 886                ;;
 887        *)
 888                case "$cur" in
 889                *:*)
 890                        local remote
 891                        case "${COMP_WORDS[0]}" in
 892                        git-push)  remote="${COMP_WORDS[1]}" ;;
 893                        git)       remote="${COMP_WORDS[2]}" ;;
 894                        esac
 895
 896                        local pfx=""
 897                        case "$COMP_WORDBREAKS" in
 898                        *:*) : great ;;
 899                        *)   pfx="${cur%%:*}:" ;;
 900                        esac
 901
 902                        __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
 903                        ;;
 904                +*)
 905                        __gitcomp "$(__git_refs)" + "${cur#+}"
 906                        ;;
 907                *)
 908                        __gitcomp "$(__git_refs)"
 909                        ;;
 910                esac
 911                ;;
 912        esac
 913}
 914
 915_git_rebase ()
 916{
 917        local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
 918        if [ -d .dotest ] || [ -d "$dir"/.dotest-merge ]; then
 919                __gitcomp "--continue --skip --abort"
 920                return
 921        fi
 922        case "${COMP_WORDS[COMP_CWORD-1]}" in
 923        -s|--strategy)
 924                __gitcomp "$(__git_merge_strategies)"
 925                return
 926        esac
 927        case "$cur" in
 928        --strategy=*)
 929                __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
 930                return
 931                ;;
 932        --*)
 933                __gitcomp "--onto --merge --strategy --interactive"
 934                return
 935        esac
 936        __gitcomp "$(__git_refs)"
 937}
 938
 939_git_send_email ()
 940{
 941        local cur="${COMP_WORDS[COMP_CWORD]}"
 942        case "$cur" in
 943        --*)
 944                __gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
 945                        --dry-run --envelope-sender --from --identity
 946                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
 947                        --no-suppress-from --no-thread --quiet
 948                        --signed-off-by-cc --smtp-pass --smtp-server
 949                        --smtp-server-port --smtp-ssl --smtp-user --subject
 950                        --suppress-cc --suppress-from --thread --to"
 951                return
 952                ;;
 953        esac
 954        COMPREPLY=()
 955}
 956
 957_git_config ()
 958{
 959        local cur="${COMP_WORDS[COMP_CWORD]}"
 960        local prv="${COMP_WORDS[COMP_CWORD-1]}"
 961        case "$prv" in
 962        branch.*.remote)
 963                __gitcomp "$(__git_remotes)"
 964                return
 965                ;;
 966        branch.*.merge)
 967                __gitcomp "$(__git_refs)"
 968                return
 969                ;;
 970        remote.*.fetch)
 971                local remote="${prv#remote.}"
 972                remote="${remote%.fetch}"
 973                __gitcomp "$(__git_refs_remotes "$remote")"
 974                return
 975                ;;
 976        remote.*.push)
 977                local remote="${prv#remote.}"
 978                remote="${remote%.push}"
 979                __gitcomp "$(git --git-dir="$(__gitdir)" \
 980                        for-each-ref --format='%(refname):%(refname)' \
 981                        refs/heads)"
 982                return
 983                ;;
 984        pull.twohead|pull.octopus)
 985                __gitcomp "$(__git_merge_strategies)"
 986                return
 987                ;;
 988        color.branch|color.diff|color.status)
 989                __gitcomp "always never auto"
 990                return
 991                ;;
 992        color.*.*)
 993                __gitcomp "
 994                        black red green yellow blue magenta cyan white
 995                        bold dim ul blink reverse
 996                        "
 997                return
 998                ;;
 999        *.*)
1000                COMPREPLY=()
1001                return
1002                ;;
1003        esac
1004        case "$cur" in
1005        --*)
1006                __gitcomp "
1007                        --global --system --file=
1008                        --list --replace-all
1009                        --get --get-all --get-regexp
1010                        --add --unset --unset-all
1011                        --remove-section --rename-section
1012                        "
1013                return
1014                ;;
1015        branch.*.*)
1016                local pfx="${cur%.*}."
1017                cur="${cur##*.}"
1018                __gitcomp "remote merge" "$pfx" "$cur"
1019                return
1020                ;;
1021        branch.*)
1022                local pfx="${cur%.*}."
1023                cur="${cur#*.}"
1024                __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1025                return
1026                ;;
1027        remote.*.*)
1028                local pfx="${cur%.*}."
1029                cur="${cur##*.}"
1030                __gitcomp "
1031                        url fetch push skipDefaultUpdate
1032                        receivepack uploadpack tagopt
1033                        " "$pfx" "$cur"
1034                return
1035                ;;
1036        remote.*)
1037                local pfx="${cur%.*}."
1038                cur="${cur#*.}"
1039                __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1040                return
1041                ;;
1042        esac
1043        __gitcomp "
1044                apply.whitespace
1045                core.fileMode
1046                core.gitProxy
1047                core.ignoreStat
1048                core.preferSymlinkRefs
1049                core.logAllRefUpdates
1050                core.loosecompression
1051                core.repositoryFormatVersion
1052                core.sharedRepository
1053                core.warnAmbiguousRefs
1054                core.compression
1055                core.packedGitWindowSize
1056                core.packedGitLimit
1057                clean.requireForce
1058                color.branch
1059                color.branch.current
1060                color.branch.local
1061                color.branch.remote
1062                color.branch.plain
1063                color.diff
1064                color.diff.plain
1065                color.diff.meta
1066                color.diff.frag
1067                color.diff.old
1068                color.diff.new
1069                color.diff.commit
1070                color.diff.whitespace
1071                color.pager
1072                color.status
1073                color.status.header
1074                color.status.added
1075                color.status.changed
1076                color.status.untracked
1077                diff.renameLimit
1078                diff.renames
1079                fetch.unpackLimit
1080                format.headers
1081                format.subjectprefix
1082                gitcvs.enabled
1083                gitcvs.logfile
1084                gitcvs.allbinary
1085                gitcvs.dbname gitcvs.dbdriver gitcvs.dbuser gitcvs.dbpass
1086                gitcvs.dbtablenameprefix
1087                gc.packrefs
1088                gc.reflogexpire
1089                gc.reflogexpireunreachable
1090                gc.rerereresolved
1091                gc.rerereunresolved
1092                http.sslVerify
1093                http.sslCert
1094                http.sslKey
1095                http.sslCAInfo
1096                http.sslCAPath
1097                http.maxRequests
1098                http.lowSpeedLimit
1099                http.lowSpeedTime
1100                http.noEPSV
1101                i18n.commitEncoding
1102                i18n.logOutputEncoding
1103                log.showroot
1104                merge.tool
1105                merge.summary
1106                merge.verbosity
1107                pack.window
1108                pack.depth
1109                pack.windowMemory
1110                pack.compression
1111                pack.deltaCacheSize
1112                pack.deltaCacheLimit
1113                pull.octopus
1114                pull.twohead
1115                repack.useDeltaBaseOffset
1116                showbranch.default
1117                tar.umask
1118                transfer.unpackLimit
1119                receive.unpackLimit
1120                receive.denyNonFastForwards
1121                user.name
1122                user.email
1123                user.signingkey
1124                branch. remote.
1125        "
1126}
1127
1128_git_remote ()
1129{
1130        local subcommands="add rm show prune update"
1131        local subcommand="$(__git_find_subcommand "$subcommands")"
1132        if [ -z "$subcommand" ]; then
1133                __gitcomp "$subcommands"
1134                return
1135        fi
1136
1137        case "$subcommand" in
1138        rm|show|prune)
1139                __gitcomp "$(__git_remotes)"
1140                ;;
1141        update)
1142                local i c='' IFS=$'\n'
1143                for i in $(git --git-dir="$(__gitdir)" config --list); do
1144                        case "$i" in
1145                        remotes.*)
1146                                i="${i#remotes.}"
1147                                c="$c ${i/=*/}"
1148                                ;;
1149                        esac
1150                done
1151                __gitcomp "$c"
1152                ;;
1153        *)
1154                COMPREPLY=()
1155                ;;
1156        esac
1157}
1158
1159_git_reset ()
1160{
1161        __git_has_doubledash && return
1162
1163        local cur="${COMP_WORDS[COMP_CWORD]}"
1164        case "$cur" in
1165        --*)
1166                __gitcomp "--mixed --hard --soft"
1167                return
1168                ;;
1169        esac
1170        __gitcomp "$(__git_refs)"
1171}
1172
1173_git_shortlog ()
1174{
1175        __git_has_doubledash && return
1176
1177        local cur="${COMP_WORDS[COMP_CWORD]}"
1178        case "$cur" in
1179        --*)
1180                __gitcomp "
1181                        --max-count= --max-age= --since= --after=
1182                        --min-age= --before= --until=
1183                        --no-merges
1184                        --author= --committer= --grep=
1185                        --all-match
1186                        --not --all
1187                        --numbered --summary
1188                        "
1189                return
1190                ;;
1191        esac
1192        __git_complete_revlist
1193}
1194
1195_git_show ()
1196{
1197        local cur="${COMP_WORDS[COMP_CWORD]}"
1198        case "$cur" in
1199        --pretty=*)
1200                __gitcomp "
1201                        oneline short medium full fuller email raw
1202                        " "" "${cur##--pretty=}"
1203                return
1204                ;;
1205        --*)
1206                __gitcomp "--pretty="
1207                return
1208                ;;
1209        esac
1210        __git_complete_file
1211}
1212
1213_git_stash ()
1214{
1215        local subcommands='save list show apply clear drop pop create'
1216        local subcommand="$(__git_find_subcommand "$subcommands")"
1217        if [ -z "$subcommand" ]; then
1218                __gitcomp "$subcommands"
1219        else
1220                local cur="${COMP_WORDS[COMP_CWORD]}"
1221                case "$subcommand,$cur" in
1222                save,--*)
1223                        __gitcomp "--keep-index"
1224                        ;;
1225                *)
1226                        COMPREPLY=()
1227                        ;;
1228                esac
1229        fi
1230}
1231
1232_git_submodule ()
1233{
1234        __git_has_doubledash && return
1235
1236        local subcommands="add status init update"
1237        if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1238                local cur="${COMP_WORDS[COMP_CWORD]}"
1239                case "$cur" in
1240                --*)
1241                        __gitcomp "--quiet --cached"
1242                        ;;
1243                *)
1244                        __gitcomp "$subcommands"
1245                        ;;
1246                esac
1247                return
1248        fi
1249}
1250
1251_git_svn ()
1252{
1253        local subcommands="
1254                init fetch clone rebase dcommit log find-rev
1255                set-tree commit-diff info create-ignore propget
1256                proplist show-ignore show-externals
1257                "
1258        local subcommand="$(__git_find_subcommand "$subcommands")"
1259        if [ -z "$subcommand" ]; then
1260                __gitcomp "$subcommands"
1261        else
1262                local remote_opts="--username= --config-dir= --no-auth-cache"
1263                local fc_opts="
1264                        --follow-parent --authors-file= --repack=
1265                        --no-metadata --use-svm-props --use-svnsync-props
1266                        --log-window-size= --no-checkout --quiet
1267                        --repack-flags --user-log-author $remote_opts
1268                        "
1269                local init_opts="
1270                        --template= --shared= --trunk= --tags=
1271                        --branches= --stdlayout --minimize-url
1272                        --no-metadata --use-svm-props --use-svnsync-props
1273                        --rewrite-root= $remote_opts
1274                        "
1275                local cmt_opts="
1276                        --edit --rmdir --find-copies-harder --copy-similarity=
1277                        "
1278
1279                local cur="${COMP_WORDS[COMP_CWORD]}"
1280                case "$subcommand,$cur" in
1281                fetch,--*)
1282                        __gitcomp "--revision= --fetch-all $fc_opts"
1283                        ;;
1284                clone,--*)
1285                        __gitcomp "--revision= $fc_opts $init_opts"
1286                        ;;
1287                init,--*)
1288                        __gitcomp "$init_opts"
1289                        ;;
1290                dcommit,--*)
1291                        __gitcomp "
1292                                --merge --strategy= --verbose --dry-run
1293                                --fetch-all --no-rebase $cmt_opts $fc_opts
1294                                "
1295                        ;;
1296                set-tree,--*)
1297                        __gitcomp "--stdin $cmt_opts $fc_opts"
1298                        ;;
1299                create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
1300                show-externals,--*)
1301                        __gitcomp "--revision="
1302                        ;;
1303                log,--*)
1304                        __gitcomp "
1305                                --limit= --revision= --verbose --incremental
1306                                --oneline --show-commit --non-recursive
1307                                --authors-file=
1308                                "
1309                        ;;
1310                rebase,--*)
1311                        __gitcomp "
1312                                --merge --verbose --strategy= --local
1313                                --fetch-all $fc_opts
1314                                "
1315                        ;;
1316                commit-diff,--*)
1317                        __gitcomp "--message= --file= --revision= $cmt_opts"
1318                        ;;
1319                info,--*)
1320                        __gitcomp "--url"
1321                        ;;
1322                *)
1323                        COMPREPLY=()
1324                        ;;
1325                esac
1326        fi
1327}
1328
1329_git_tag ()
1330{
1331        local i c=1 f=0
1332        while [ $c -lt $COMP_CWORD ]; do
1333                i="${COMP_WORDS[c]}"
1334                case "$i" in
1335                -d|-v)
1336                        __gitcomp "$(__git_tags)"
1337                        return
1338                        ;;
1339                -f)
1340                        f=1
1341                        ;;
1342                esac
1343                c=$((++c))
1344        done
1345
1346        case "${COMP_WORDS[COMP_CWORD-1]}" in
1347        -m|-F)
1348                COMPREPLY=()
1349                ;;
1350        -*|tag|git-tag)
1351                if [ $f = 1 ]; then
1352                        __gitcomp "$(__git_tags)"
1353                else
1354                        COMPREPLY=()
1355                fi
1356                ;;
1357        *)
1358                __gitcomp "$(__git_refs)"
1359                ;;
1360        esac
1361}
1362
1363_git ()
1364{
1365        local i c=1 command __git_dir
1366
1367        while [ $c -lt $COMP_CWORD ]; do
1368                i="${COMP_WORDS[c]}"
1369                case "$i" in
1370                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
1371                --bare)      __git_dir="." ;;
1372                --version|--help|-p|--paginate) ;;
1373                *) command="$i"; break ;;
1374                esac
1375                c=$((++c))
1376        done
1377
1378        if [ -z "$command" ]; then
1379                case "${COMP_WORDS[COMP_CWORD]}" in
1380                --*=*) COMPREPLY=() ;;
1381                --*)   __gitcomp "
1382                        --paginate
1383                        --no-pager
1384                        --git-dir=
1385                        --bare
1386                        --version
1387                        --exec-path
1388                        --work-tree=
1389                        --help
1390                        "
1391                        ;;
1392                *)     __gitcomp "$(__git_commands) $(__git_aliases)" ;;
1393                esac
1394                return
1395        fi
1396
1397        local expansion=$(__git_aliased_command "$command")
1398        [ "$expansion" ] && command="$expansion"
1399
1400        case "$command" in
1401        am)          _git_am ;;
1402        add)         _git_add ;;
1403        apply)       _git_apply ;;
1404        bisect)      _git_bisect ;;
1405        bundle)      _git_bundle ;;
1406        branch)      _git_branch ;;
1407        checkout)    _git_checkout ;;
1408        cherry)      _git_cherry ;;
1409        cherry-pick) _git_cherry_pick ;;
1410        commit)      _git_commit ;;
1411        config)      _git_config ;;
1412        describe)    _git_describe ;;
1413        diff)        _git_diff ;;
1414        fetch)       _git_fetch ;;
1415        format-patch) _git_format_patch ;;
1416        gc)          _git_gc ;;
1417        log)         _git_log ;;
1418        ls-remote)   _git_ls_remote ;;
1419        ls-tree)     _git_ls_tree ;;
1420        merge)       _git_merge;;
1421        merge-base)  _git_merge_base ;;
1422        name-rev)    _git_name_rev ;;
1423        pull)        _git_pull ;;
1424        push)        _git_push ;;
1425        rebase)      _git_rebase ;;
1426        remote)      _git_remote ;;
1427        reset)       _git_reset ;;
1428        send-email)  _git_send_email ;;
1429        shortlog)    _git_shortlog ;;
1430        show)        _git_show ;;
1431        show-branch) _git_log ;;
1432        stash)       _git_stash ;;
1433        submodule)   _git_submodule ;;
1434        svn)         _git_svn ;;
1435        tag)         _git_tag ;;
1436        whatchanged) _git_log ;;
1437        *)           COMPREPLY=() ;;
1438        esac
1439}
1440
1441_gitk ()
1442{
1443        __git_has_doubledash && return
1444
1445        local cur="${COMP_WORDS[COMP_CWORD]}"
1446        local g="$(git rev-parse --git-dir 2>/dev/null)"
1447        local merge=""
1448        if [ -f $g/MERGE_HEAD ]; then
1449                merge="--merge"
1450        fi
1451        case "$cur" in
1452        --*)
1453                __gitcomp "--not --all $merge"
1454                return
1455                ;;
1456        esac
1457        __git_complete_revlist
1458}
1459
1460complete -o default -o nospace -F _git git
1461complete -o default -o nospace -F _gitk gitk
1462complete -o default -o nospace -F _git_am git-am
1463complete -o default -o nospace -F _git_apply git-apply
1464complete -o default -o nospace -F _git_bisect git-bisect
1465complete -o default -o nospace -F _git_branch git-branch
1466complete -o default -o nospace -F _git_bundle git-bundle
1467complete -o default -o nospace -F _git_checkout git-checkout
1468complete -o default -o nospace -F _git_cherry git-cherry
1469complete -o default -o nospace -F _git_cherry_pick git-cherry-pick
1470complete -o default -o nospace -F _git_commit git-commit
1471complete -o default -o nospace -F _git_describe git-describe
1472complete -o default -o nospace -F _git_diff git-diff
1473complete -o default -o nospace -F _git_fetch git-fetch
1474complete -o default -o nospace -F _git_format_patch git-format-patch
1475complete -o default -o nospace -F _git_gc git-gc
1476complete -o default -o nospace -F _git_log git-log
1477complete -o default -o nospace -F _git_ls_remote git-ls-remote
1478complete -o default -o nospace -F _git_ls_tree git-ls-tree
1479complete -o default -o nospace -F _git_merge git-merge
1480complete -o default -o nospace -F _git_merge_base git-merge-base
1481complete -o default -o nospace -F _git_name_rev git-name-rev
1482complete -o default -o nospace -F _git_pull git-pull
1483complete -o default -o nospace -F _git_push git-push
1484complete -o default -o nospace -F _git_rebase git-rebase
1485complete -o default -o nospace -F _git_config git-config
1486complete -o default -o nospace -F _git_remote git-remote
1487complete -o default -o nospace -F _git_reset git-reset
1488complete -o default -o nospace -F _git_send_email git-send-email
1489complete -o default -o nospace -F _git_shortlog git-shortlog
1490complete -o default -o nospace -F _git_show git-show
1491complete -o default -o nospace -F _git_stash git-stash
1492complete -o default -o nospace -F _git_submodule git-submodule
1493complete -o default -o nospace -F _git_svn git-svn
1494complete -o default -o nospace -F _git_log git-show-branch
1495complete -o default -o nospace -F _git_tag git-tag
1496complete -o default -o nospace -F _git_log git-whatchanged
1497
1498# The following are necessary only for Cygwin, and only are needed
1499# when the user has tab-completed the executable name and consequently
1500# included the '.exe' suffix.
1501#
1502if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1503complete -o default -o nospace -F _git_add git-add.exe
1504complete -o default -o nospace -F _git_apply git-apply.exe
1505complete -o default -o nospace -F _git git.exe
1506complete -o default -o nospace -F _git_branch git-branch.exe
1507complete -o default -o nospace -F _git_bundle git-bundle.exe
1508complete -o default -o nospace -F _git_cherry git-cherry.exe
1509complete -o default -o nospace -F _git_describe git-describe.exe
1510complete -o default -o nospace -F _git_diff git-diff.exe
1511complete -o default -o nospace -F _git_format_patch git-format-patch.exe
1512complete -o default -o nospace -F _git_log git-log.exe
1513complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
1514complete -o default -o nospace -F _git_merge_base git-merge-base.exe
1515complete -o default -o nospace -F _git_name_rev git-name-rev.exe
1516complete -o default -o nospace -F _git_push git-push.exe
1517complete -o default -o nospace -F _git_config git-config
1518complete -o default -o nospace -F _git_shortlog git-shortlog.exe
1519complete -o default -o nospace -F _git_show git-show.exe
1520complete -o default -o nospace -F _git_log git-show-branch.exe
1521complete -o default -o nospace -F _git_tag git-tag.exe
1522complete -o default -o nospace -F _git_log git-whatchanged.exe
1523fi