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