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