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