contrib / completion / git-completion.bashon commit Merge branch 'jc/maint-svn-info-test-fix' (f1f7677)
   1#!bash
   2#
   3# bash completion support for core Git.
   4#
   5# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
   6# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
   7# Distributed under the GNU General Public License, version 2.0.
   8#
   9# The contained completion routines provide support for completing:
  10#
  11#    *) local and remote branch names
  12#    *) local and remote tag names
  13#    *) .git/remotes file names
  14#    *) git 'subcommands'
  15#    *) tree paths within 'ref:path/to/file' expressions
  16#    *) common --long-options
  17#
  18# To use these routines:
  19#
  20#    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
  21#    2) Added the following line to your .bashrc:
  22#        source ~/.git-completion.sh
  23#
  24#       Or, add the following lines to your .zshrc:
  25#        autoload bashcompinit
  26#        bashcompinit
  27#        source ~/.git-completion.sh
  28#
  29#    3) 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#       In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty
  37#       value, unstaged (*) and staged (+) changes will be shown next
  38#       to the branch name.  You can configure this per-repository
  39#       with the bash.showDirtyState variable, which defaults to true
  40#       once GIT_PS1_SHOWDIRTYSTATE is enabled.
  41#
  42#       You can also see if currently something is stashed, by setting
  43#       GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
  44#       then a '$' will be shown next to the branch name.
  45#
  46#       If you would like to see if there're untracked files, then you can
  47#       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
  48#       untracked files, then a '%' will be shown next to the branch name.
  49#
  50#       If you would like to see the difference between HEAD and its
  51#       upstream, set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates
  52#       you are behind, ">" indicates you are ahead, and "<>"
  53#       indicates you have diverged.  You can further control
  54#       behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated
  55#       list of values:
  56#           verbose       show number of commits ahead/behind (+/-) upstream
  57#           legacy        don't use the '--count' option available in recent
  58#                         versions of git-rev-list
  59#           git           always compare HEAD to @{upstream}
  60#           svn           always compare HEAD to your SVN upstream
  61#       By default, __git_ps1 will compare HEAD to your SVN upstream
  62#       if it can find one, or @{upstream} otherwise.  Once you have
  63#       set GIT_PS1_SHOWUPSTREAM, you can override it on a
  64#       per-repository basis by setting the bash.showUpstream config
  65#       variable.
  66#
  67#
  68# To submit patches:
  69#
  70#    *) Read Documentation/SubmittingPatches
  71#    *) Send all patches to the current maintainer:
  72#
  73#       "Shawn O. Pearce" <spearce@spearce.org>
  74#
  75#    *) Always CC the Git mailing list:
  76#
  77#       git@vger.kernel.org
  78#
  79
  80case "$COMP_WORDBREAKS" in
  81*:*) : great ;;
  82*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
  83esac
  84
  85# __gitdir accepts 0 or 1 arguments (i.e., location)
  86# returns location of .git repo
  87__gitdir ()
  88{
  89        if [ -z "${1-}" ]; then
  90                if [ -n "${__git_dir-}" ]; then
  91                        echo "$__git_dir"
  92                elif [ -d .git ]; then
  93                        echo .git
  94                else
  95                        git rev-parse --git-dir 2>/dev/null
  96                fi
  97        elif [ -d "$1/.git" ]; then
  98                echo "$1/.git"
  99        else
 100                echo "$1"
 101        fi
 102}
 103
 104# stores the divergence from upstream in $p
 105# used by GIT_PS1_SHOWUPSTREAM
 106__git_ps1_show_upstream ()
 107{
 108        local key value
 109        local svn_remote=() svn_url_pattern count n
 110        local upstream=git legacy="" verbose=""
 111
 112        # get some config options from git-config
 113        while read key value; do
 114                case "$key" in
 115                bash.showupstream)
 116                        GIT_PS1_SHOWUPSTREAM="$value"
 117                        if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
 118                                p=""
 119                                return
 120                        fi
 121                        ;;
 122                svn-remote.*.url)
 123                        svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
 124                        svn_url_pattern+="\\|$value"
 125                        upstream=svn+git # default upstream is SVN if available, else git
 126                        ;;
 127                esac
 128        done < <(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')
 129
 130        # parse configuration values
 131        for option in ${GIT_PS1_SHOWUPSTREAM}; do
 132                case "$option" in
 133                git|svn) upstream="$option" ;;
 134                verbose) verbose=1 ;;
 135                legacy)  legacy=1  ;;
 136                esac
 137        done
 138
 139        # Find our upstream
 140        case "$upstream" in
 141        git)    upstream="@{upstream}" ;;
 142        svn*)
 143                # get the upstream from the "git-svn-id: ..." in a commit message
 144                # (git-svn uses essentially the same procedure internally)
 145                local svn_upstream=($(git log --first-parent -1 \
 146                                        --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
 147                if [[ 0 -ne ${#svn_upstream[@]} ]]; then
 148                        svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
 149                        svn_upstream=${svn_upstream%@*}
 150                        local n_stop="${#svn_remote[@]}"
 151                        for ((n=1; n <= n_stop; ++n)); do
 152                                svn_upstream=${svn_upstream#${svn_remote[$n]}}
 153                        done
 154
 155                        if [[ -z "$svn_upstream" ]]; then
 156                                # default branch name for checkouts with no layout:
 157                                upstream=${GIT_SVN_ID:-git-svn}
 158                        else
 159                                upstream=${svn_upstream#/}
 160                        fi
 161                elif [[ "svn+git" = "$upstream" ]]; then
 162                        upstream="@{upstream}"
 163                fi
 164                ;;
 165        esac
 166
 167        # Find how many commits we are ahead/behind our upstream
 168        if [[ -z "$legacy" ]]; then
 169                count="$(git rev-list --count --left-right \
 170                                "$upstream"...HEAD 2>/dev/null)"
 171        else
 172                # produce equivalent output to --count for older versions of git
 173                local commits
 174                if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
 175                then
 176                        local commit behind=0 ahead=0
 177                        for commit in $commits
 178                        do
 179                                case "$commit" in
 180                                "<"*) let ++behind
 181                                        ;;
 182                                *)    let ++ahead
 183                                        ;;
 184                                esac
 185                        done
 186                        count="$behind  $ahead"
 187                else
 188                        count=""
 189                fi
 190        fi
 191
 192        # calculate the result
 193        if [[ -z "$verbose" ]]; then
 194                case "$count" in
 195                "") # no upstream
 196                        p="" ;;
 197                "0      0") # equal to upstream
 198                        p="=" ;;
 199                "0      "*) # ahead of upstream
 200                        p=">" ;;
 201                *"      0") # behind upstream
 202                        p="<" ;;
 203                *)          # diverged from upstream
 204                        p="<>" ;;
 205                esac
 206        else
 207                case "$count" in
 208                "") # no upstream
 209                        p="" ;;
 210                "0      0") # equal to upstream
 211                        p=" u=" ;;
 212                "0      "*) # ahead of upstream
 213                        p=" u+${count#0 }" ;;
 214                *"      0") # behind upstream
 215                        p=" u-${count%  0}" ;;
 216                *)          # diverged from upstream
 217                        p=" u+${count#* }-${count%      *}" ;;
 218                esac
 219        fi
 220
 221}
 222
 223
 224# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
 225# returns text to add to bash PS1 prompt (includes branch name)
 226__git_ps1 ()
 227{
 228        local g="$(__gitdir)"
 229        if [ -n "$g" ]; then
 230                local r=""
 231                local b=""
 232                if [ -f "$g/rebase-merge/interactive" ]; then
 233                        r="|REBASE-i"
 234                        b="$(cat "$g/rebase-merge/head-name")"
 235                elif [ -d "$g/rebase-merge" ]; then
 236                        r="|REBASE-m"
 237                        b="$(cat "$g/rebase-merge/head-name")"
 238                else
 239                        if [ -d "$g/rebase-apply" ]; then
 240                                if [ -f "$g/rebase-apply/rebasing" ]; then
 241                                        r="|REBASE"
 242                                elif [ -f "$g/rebase-apply/applying" ]; then
 243                                        r="|AM"
 244                                else
 245                                        r="|AM/REBASE"
 246                                fi
 247                        elif [ -f "$g/MERGE_HEAD" ]; then
 248                                r="|MERGING"
 249                        elif [ -f "$g/BISECT_LOG" ]; then
 250                                r="|BISECTING"
 251                        fi
 252
 253                        b="$(git symbolic-ref HEAD 2>/dev/null)" || {
 254
 255                                b="$(
 256                                case "${GIT_PS1_DESCRIBE_STYLE-}" in
 257                                (contains)
 258                                        git describe --contains HEAD ;;
 259                                (branch)
 260                                        git describe --contains --all HEAD ;;
 261                                (describe)
 262                                        git describe HEAD ;;
 263                                (* | default)
 264                                        git describe --tags --exact-match HEAD ;;
 265                                esac 2>/dev/null)" ||
 266
 267                                b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
 268                                b="unknown"
 269                                b="($b)"
 270                        }
 271                fi
 272
 273                local w=""
 274                local i=""
 275                local s=""
 276                local u=""
 277                local c=""
 278                local p=""
 279
 280                if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
 281                        if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
 282                                c="BARE:"
 283                        else
 284                                b="GIT_DIR!"
 285                        fi
 286                elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
 287                        if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
 288                                if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
 289                                        git diff --no-ext-diff --quiet --exit-code || w="*"
 290                                        if git rev-parse --quiet --verify HEAD >/dev/null; then
 291                                                git diff-index --cached --quiet HEAD -- || i="+"
 292                                        else
 293                                                i="#"
 294                                        fi
 295                                fi
 296                        fi
 297                        if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
 298                                git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
 299                        fi
 300
 301                        if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
 302                           if [ -n "$(git ls-files --others --exclude-standard)" ]; then
 303                              u="%"
 304                           fi
 305                        fi
 306
 307                        if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
 308                                __git_ps1_show_upstream
 309                        fi
 310                fi
 311
 312                local f="$w$i$s$u"
 313                printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
 314        fi
 315}
 316
 317# __gitcomp_1 requires 2 arguments
 318__gitcomp_1 ()
 319{
 320        local c IFS=' '$'\t'$'\n'
 321        for c in $1; do
 322                case "$c$2" in
 323                --*=*) printf %s$'\n' "$c$2" ;;
 324                *.)    printf %s$'\n' "$c$2" ;;
 325                *)     printf %s$'\n' "$c$2 " ;;
 326                esac
 327        done
 328}
 329
 330# __gitcomp accepts 1, 2, 3, or 4 arguments
 331# generates completion reply with compgen
 332__gitcomp ()
 333{
 334        local cur="${COMP_WORDS[COMP_CWORD]}"
 335        if [ $# -gt 2 ]; then
 336                cur="$3"
 337        fi
 338        case "$cur" in
 339        --*=)
 340                COMPREPLY=()
 341                ;;
 342        *)
 343                local IFS=$'\n'
 344                COMPREPLY=($(compgen -P "${2-}" \
 345                        -W "$(__gitcomp_1 "${1-}" "${4-}")" \
 346                        -- "$cur"))
 347                ;;
 348        esac
 349}
 350
 351# __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
 352__git_heads ()
 353{
 354        local cmd i is_hash=y dir="$(__gitdir "${1-}")"
 355        if [ -d "$dir" ]; then
 356                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
 357                        refs/heads
 358                return
 359        fi
 360        for i in $(git ls-remote "${1-}" 2>/dev/null); do
 361                case "$is_hash,$i" in
 362                y,*) is_hash=n ;;
 363                n,*^{}) is_hash=y ;;
 364                n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
 365                n,*) is_hash=y; echo "$i" ;;
 366                esac
 367        done
 368}
 369
 370# __git_tags accepts 0 or 1 arguments (to pass to __gitdir)
 371__git_tags ()
 372{
 373        local cmd i is_hash=y dir="$(__gitdir "${1-}")"
 374        if [ -d "$dir" ]; then
 375                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
 376                        refs/tags
 377                return
 378        fi
 379        for i in $(git ls-remote "${1-}" 2>/dev/null); do
 380                case "$is_hash,$i" in
 381                y,*) is_hash=n ;;
 382                n,*^{}) is_hash=y ;;
 383                n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
 384                n,*) is_hash=y; echo "$i" ;;
 385                esac
 386        done
 387}
 388
 389# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
 390# presence of 2nd argument means use the guess heuristic employed
 391# by checkout for tracking branches
 392__git_refs ()
 393{
 394        local i is_hash=y dir="$(__gitdir "${1-}")" track="${2-}"
 395        local cur="${COMP_WORDS[COMP_CWORD]}" format refs
 396        if [ -d "$dir" ]; then
 397                case "$cur" in
 398                refs|refs/*)
 399                        format="refname"
 400                        refs="${cur%/*}"
 401                        track=""
 402                        ;;
 403                *)
 404                        for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
 405                                if [ -e "$dir/$i" ]; then echo $i; fi
 406                        done
 407                        format="refname:short"
 408                        refs="refs/tags refs/heads refs/remotes"
 409                        ;;
 410                esac
 411                git --git-dir="$dir" for-each-ref --format="%($format)" \
 412                        $refs
 413                if [ -n "$track" ]; then
 414                        # employ the heuristic used by git checkout
 415                        # Try to find a remote branch that matches the completion word
 416                        # but only output if the branch name is unique
 417                        local ref entry
 418                        git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \
 419                                "refs/remotes/" | \
 420                        while read entry; do
 421                                eval "$entry"
 422                                ref="${ref#*/}"
 423                                if [[ "$ref" == "$cur"* ]]; then
 424                                        echo "$ref"
 425                                fi
 426                        done | uniq -u
 427                fi
 428                return
 429        fi
 430        for i in $(git ls-remote "$dir" 2>/dev/null); do
 431                case "$is_hash,$i" in
 432                y,*) is_hash=n ;;
 433                n,*^{}) is_hash=y ;;
 434                n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
 435                n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
 436                n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
 437                n,*) is_hash=y; echo "$i" ;;
 438                esac
 439        done
 440}
 441
 442# __git_refs2 requires 1 argument (to pass to __git_refs)
 443__git_refs2 ()
 444{
 445        local i
 446        for i in $(__git_refs "$1"); do
 447                echo "$i:$i"
 448        done
 449}
 450
 451# __git_refs_remotes requires 1 argument (to pass to ls-remote)
 452__git_refs_remotes ()
 453{
 454        local cmd i is_hash=y
 455        for i in $(git ls-remote "$1" 2>/dev/null); do
 456                case "$is_hash,$i" in
 457                n,refs/heads/*)
 458                        is_hash=y
 459                        echo "$i:refs/remotes/$1/${i#refs/heads/}"
 460                        ;;
 461                y,*) is_hash=n ;;
 462                n,*^{}) is_hash=y ;;
 463                n,refs/tags/*) is_hash=y;;
 464                n,*) is_hash=y; ;;
 465                esac
 466        done
 467}
 468
 469__git_remotes ()
 470{
 471        local i ngoff IFS=$'\n' d="$(__gitdir)"
 472        shopt -q nullglob || ngoff=1
 473        shopt -s nullglob
 474        for i in "$d/remotes"/*; do
 475                echo ${i#$d/remotes/}
 476        done
 477        [ "$ngoff" ] && shopt -u nullglob
 478        for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
 479                i="${i#remote.}"
 480                echo "${i/.url*/}"
 481        done
 482}
 483
 484__git_list_merge_strategies ()
 485{
 486        git merge -s help 2>&1 |
 487        sed -n -e '/[Aa]vailable strategies are: /,/^$/{
 488                s/\.$//
 489                s/.*://
 490                s/^[    ]*//
 491                s/[     ]*$//
 492                p
 493        }'
 494}
 495
 496__git_merge_strategies=
 497# 'git merge -s help' (and thus detection of the merge strategy
 498# list) fails, unfortunately, if run outside of any git working
 499# tree.  __git_merge_strategies is set to the empty string in
 500# that case, and the detection will be repeated the next time it
 501# is needed.
 502__git_compute_merge_strategies ()
 503{
 504        : ${__git_merge_strategies:=$(__git_list_merge_strategies)}
 505}
 506
 507__git_complete_file ()
 508{
 509        local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
 510        case "$cur" in
 511        ?*:*)
 512                ref="${cur%%:*}"
 513                cur="${cur#*:}"
 514                case "$cur" in
 515                ?*/*)
 516                        pfx="${cur%/*}"
 517                        cur="${cur##*/}"
 518                        ls="$ref:$pfx"
 519                        pfx="$pfx/"
 520                        ;;
 521                *)
 522                        ls="$ref"
 523                        ;;
 524            esac
 525
 526                case "$COMP_WORDBREAKS" in
 527                *:*) : great ;;
 528                *)   pfx="$ref:$pfx" ;;
 529                esac
 530
 531                local IFS=$'\n'
 532                COMPREPLY=($(compgen -P "$pfx" \
 533                        -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
 534                                | sed '/^100... blob /{
 535                                           s,^.*        ,,
 536                                           s,$, ,
 537                                       }
 538                                       /^120000 blob /{
 539                                           s,^.*        ,,
 540                                           s,$, ,
 541                                       }
 542                                       /^040000 tree /{
 543                                           s,^.*        ,,
 544                                           s,$,/,
 545                                       }
 546                                       s/^.*    //')" \
 547                        -- "$cur"))
 548                ;;
 549        *)
 550                __gitcomp "$(__git_refs)"
 551                ;;
 552        esac
 553}
 554
 555__git_complete_revlist ()
 556{
 557        local pfx cur="${COMP_WORDS[COMP_CWORD]}"
 558        case "$cur" in
 559        *...*)
 560                pfx="${cur%...*}..."
 561                cur="${cur#*...}"
 562                __gitcomp "$(__git_refs)" "$pfx" "$cur"
 563                ;;
 564        *..*)
 565                pfx="${cur%..*}.."
 566                cur="${cur#*..}"
 567                __gitcomp "$(__git_refs)" "$pfx" "$cur"
 568                ;;
 569        *)
 570                __gitcomp "$(__git_refs)"
 571                ;;
 572        esac
 573}
 574
 575__git_complete_remote_or_refspec ()
 576{
 577        local cmd="${COMP_WORDS[1]}"
 578        local cur="${COMP_WORDS[COMP_CWORD]}"
 579        local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
 580        while [ $c -lt $COMP_CWORD ]; do
 581                i="${COMP_WORDS[c]}"
 582                case "$i" in
 583                --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
 584                --all)
 585                        case "$cmd" in
 586                        push) no_complete_refspec=1 ;;
 587                        fetch)
 588                                COMPREPLY=()
 589                                return
 590                                ;;
 591                        *) ;;
 592                        esac
 593                        ;;
 594                -*) ;;
 595                *) remote="$i"; break ;;
 596                esac
 597                c=$((++c))
 598        done
 599        if [ -z "$remote" ]; then
 600                __gitcomp "$(__git_remotes)"
 601                return
 602        fi
 603        if [ $no_complete_refspec = 1 ]; then
 604                COMPREPLY=()
 605                return
 606        fi
 607        [ "$remote" = "." ] && remote=
 608        case "$cur" in
 609        *:*)
 610                case "$COMP_WORDBREAKS" in
 611                *:*) : great ;;
 612                *)   pfx="${cur%%:*}:" ;;
 613                esac
 614                cur="${cur#*:}"
 615                lhs=0
 616                ;;
 617        +*)
 618                pfx="+"
 619                cur="${cur#+}"
 620                ;;
 621        esac
 622        case "$cmd" in
 623        fetch)
 624                if [ $lhs = 1 ]; then
 625                        __gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur"
 626                else
 627                        __gitcomp "$(__git_refs)" "$pfx" "$cur"
 628                fi
 629                ;;
 630        pull)
 631                if [ $lhs = 1 ]; then
 632                        __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
 633                else
 634                        __gitcomp "$(__git_refs)" "$pfx" "$cur"
 635                fi
 636                ;;
 637        push)
 638                if [ $lhs = 1 ]; then
 639                        __gitcomp "$(__git_refs)" "$pfx" "$cur"
 640                else
 641                        __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
 642                fi
 643                ;;
 644        esac
 645}
 646
 647__git_complete_strategy ()
 648{
 649        __git_compute_merge_strategies
 650        case "${COMP_WORDS[COMP_CWORD-1]}" in
 651        -s|--strategy)
 652                __gitcomp "$__git_merge_strategies"
 653                return 0
 654        esac
 655        local cur="${COMP_WORDS[COMP_CWORD]}"
 656        case "$cur" in
 657        --strategy=*)
 658                __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
 659                return 0
 660                ;;
 661        esac
 662        return 1
 663}
 664
 665__git_list_all_commands ()
 666{
 667        local i IFS=" "$'\n'
 668        for i in $(git help -a|egrep '^  [a-zA-Z0-9]')
 669        do
 670                case $i in
 671                *--*)             : helper pattern;;
 672                *) echo $i;;
 673                esac
 674        done
 675}
 676
 677__git_all_commands=
 678__git_compute_all_commands ()
 679{
 680        : ${__git_all_commands:=$(__git_list_all_commands)}
 681}
 682
 683__git_list_porcelain_commands ()
 684{
 685        local i IFS=" "$'\n'
 686        __git_compute_all_commands
 687        for i in "help" $__git_all_commands
 688        do
 689                case $i in
 690                *--*)             : helper pattern;;
 691                applymbox)        : ask gittus;;
 692                applypatch)       : ask gittus;;
 693                archimport)       : import;;
 694                cat-file)         : plumbing;;
 695                check-attr)       : plumbing;;
 696                check-ref-format) : plumbing;;
 697                checkout-index)   : plumbing;;
 698                commit-tree)      : plumbing;;
 699                count-objects)    : infrequent;;
 700                cvsexportcommit)  : export;;
 701                cvsimport)        : import;;
 702                cvsserver)        : daemon;;
 703                daemon)           : daemon;;
 704                diff-files)       : plumbing;;
 705                diff-index)       : plumbing;;
 706                diff-tree)        : plumbing;;
 707                fast-import)      : import;;
 708                fast-export)      : export;;
 709                fsck-objects)     : plumbing;;
 710                fetch-pack)       : plumbing;;
 711                fmt-merge-msg)    : plumbing;;
 712                for-each-ref)     : plumbing;;
 713                hash-object)      : plumbing;;
 714                http-*)           : transport;;
 715                index-pack)       : plumbing;;
 716                init-db)          : deprecated;;
 717                local-fetch)      : plumbing;;
 718                lost-found)       : infrequent;;
 719                ls-files)         : plumbing;;
 720                ls-remote)        : plumbing;;
 721                ls-tree)          : plumbing;;
 722                mailinfo)         : plumbing;;
 723                mailsplit)        : plumbing;;
 724                merge-*)          : plumbing;;
 725                mktree)           : plumbing;;
 726                mktag)            : plumbing;;
 727                pack-objects)     : plumbing;;
 728                pack-redundant)   : plumbing;;
 729                pack-refs)        : plumbing;;
 730                parse-remote)     : plumbing;;
 731                patch-id)         : plumbing;;
 732                peek-remote)      : plumbing;;
 733                prune)            : plumbing;;
 734                prune-packed)     : plumbing;;
 735                quiltimport)      : import;;
 736                read-tree)        : plumbing;;
 737                receive-pack)     : plumbing;;
 738                reflog)           : plumbing;;
 739                remote-*)         : transport;;
 740                repo-config)      : deprecated;;
 741                rerere)           : plumbing;;
 742                rev-list)         : plumbing;;
 743                rev-parse)        : plumbing;;
 744                runstatus)        : plumbing;;
 745                sh-setup)         : internal;;
 746                shell)            : daemon;;
 747                show-ref)         : plumbing;;
 748                send-pack)        : plumbing;;
 749                show-index)       : plumbing;;
 750                ssh-*)            : transport;;
 751                stripspace)       : plumbing;;
 752                symbolic-ref)     : plumbing;;
 753                tar-tree)         : deprecated;;
 754                unpack-file)      : plumbing;;
 755                unpack-objects)   : plumbing;;
 756                update-index)     : plumbing;;
 757                update-ref)       : plumbing;;
 758                update-server-info) : daemon;;
 759                upload-archive)   : plumbing;;
 760                upload-pack)      : plumbing;;
 761                write-tree)       : plumbing;;
 762                var)              : infrequent;;
 763                verify-pack)      : infrequent;;
 764                verify-tag)       : plumbing;;
 765                *) echo $i;;
 766                esac
 767        done
 768}
 769
 770__git_porcelain_commands=
 771__git_compute_porcelain_commands ()
 772{
 773        __git_compute_all_commands
 774        : ${__git_porcelain_commands:=$(__git_list_porcelain_commands)}
 775}
 776
 777__git_pretty_aliases ()
 778{
 779        local i IFS=$'\n'
 780        for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do
 781                case "$i" in
 782                pretty.*)
 783                        i="${i#pretty.}"
 784                        echo "${i/ */}"
 785                        ;;
 786                esac
 787        done
 788}
 789
 790__git_aliases ()
 791{
 792        local i IFS=$'\n'
 793        for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
 794                case "$i" in
 795                alias.*)
 796                        i="${i#alias.}"
 797                        echo "${i/ */}"
 798                        ;;
 799                esac
 800        done
 801}
 802
 803# __git_aliased_command requires 1 argument
 804__git_aliased_command ()
 805{
 806        local word cmdline=$(git --git-dir="$(__gitdir)" \
 807                config --get "alias.$1")
 808        for word in $cmdline; do
 809                case "$word" in
 810                \!gitk|gitk)
 811                        echo "gitk"
 812                        return
 813                        ;;
 814                \!*)    : shell command alias ;;
 815                -*)     : option ;;
 816                *=*)    : setting env ;;
 817                git)    : git itself ;;
 818                *)
 819                        echo "$word"
 820                        return
 821                esac
 822        done
 823}
 824
 825# __git_find_on_cmdline requires 1 argument
 826__git_find_on_cmdline ()
 827{
 828        local word subcommand c=1
 829
 830        while [ $c -lt $COMP_CWORD ]; do
 831                word="${COMP_WORDS[c]}"
 832                for subcommand in $1; do
 833                        if [ "$subcommand" = "$word" ]; then
 834                                echo "$subcommand"
 835                                return
 836                        fi
 837                done
 838                c=$((++c))
 839        done
 840}
 841
 842__git_has_doubledash ()
 843{
 844        local c=1
 845        while [ $c -lt $COMP_CWORD ]; do
 846                if [ "--" = "${COMP_WORDS[c]}" ]; then
 847                        return 0
 848                fi
 849                c=$((++c))
 850        done
 851        return 1
 852}
 853
 854__git_whitespacelist="nowarn warn error error-all fix"
 855
 856_git_am ()
 857{
 858        local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
 859        if [ -d "$dir"/rebase-apply ]; then
 860                __gitcomp "--skip --continue --resolved --abort"
 861                return
 862        fi
 863        case "$cur" in
 864        --whitespace=*)
 865                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 866                return
 867                ;;
 868        --*)
 869                __gitcomp "
 870                        --3way --committer-date-is-author-date --ignore-date
 871                        --ignore-whitespace --ignore-space-change
 872                        --interactive --keep --no-utf8 --signoff --utf8
 873                        --whitespace= --scissors
 874                        "
 875                return
 876        esac
 877        COMPREPLY=()
 878}
 879
 880_git_apply ()
 881{
 882        local cur="${COMP_WORDS[COMP_CWORD]}"
 883        case "$cur" in
 884        --whitespace=*)
 885                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 886                return
 887                ;;
 888        --*)
 889                __gitcomp "
 890                        --stat --numstat --summary --check --index
 891                        --cached --index-info --reverse --reject --unidiff-zero
 892                        --apply --no-add --exclude=
 893                        --ignore-whitespace --ignore-space-change
 894                        --whitespace= --inaccurate-eof --verbose
 895                        "
 896                return
 897        esac
 898        COMPREPLY=()
 899}
 900
 901_git_add ()
 902{
 903        __git_has_doubledash && return
 904
 905        local cur="${COMP_WORDS[COMP_CWORD]}"
 906        case "$cur" in
 907        --*)
 908                __gitcomp "
 909                        --interactive --refresh --patch --update --dry-run
 910                        --ignore-errors --intent-to-add
 911                        "
 912                return
 913        esac
 914        COMPREPLY=()
 915}
 916
 917_git_archive ()
 918{
 919        local cur="${COMP_WORDS[COMP_CWORD]}"
 920        case "$cur" in
 921        --format=*)
 922                __gitcomp "$(git archive --list)" "" "${cur##--format=}"
 923                return
 924                ;;
 925        --remote=*)
 926                __gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
 927                return
 928                ;;
 929        --*)
 930                __gitcomp "
 931                        --format= --list --verbose
 932                        --prefix= --remote= --exec=
 933                        "
 934                return
 935                ;;
 936        esac
 937        __git_complete_file
 938}
 939
 940_git_bisect ()
 941{
 942        __git_has_doubledash && return
 943
 944        local subcommands="start bad good skip reset visualize replay log run"
 945        local subcommand="$(__git_find_on_cmdline "$subcommands")"
 946        if [ -z "$subcommand" ]; then
 947                if [ -f "$(__gitdir)"/BISECT_START ]; then
 948                        __gitcomp "$subcommands"
 949                else
 950                        __gitcomp "replay start"
 951                fi
 952                return
 953        fi
 954
 955        case "$subcommand" in
 956        bad|good|reset|skip|start)
 957                __gitcomp "$(__git_refs)"
 958                ;;
 959        *)
 960                COMPREPLY=()
 961                ;;
 962        esac
 963}
 964
 965_git_branch ()
 966{
 967        local i c=1 only_local_ref="n" has_r="n"
 968
 969        while [ $c -lt $COMP_CWORD ]; do
 970                i="${COMP_WORDS[c]}"
 971                case "$i" in
 972                -d|-m)  only_local_ref="y" ;;
 973                -r)     has_r="y" ;;
 974                esac
 975                c=$((++c))
 976        done
 977
 978        case "${COMP_WORDS[COMP_CWORD]}" in
 979        --*)
 980                __gitcomp "
 981                        --color --no-color --verbose --abbrev= --no-abbrev
 982                        --track --no-track --contains --merged --no-merged
 983                        --set-upstream
 984                        "
 985                ;;
 986        *)
 987                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
 988                        __gitcomp "$(__git_heads)"
 989                else
 990                        __gitcomp "$(__git_refs)"
 991                fi
 992                ;;
 993        esac
 994}
 995
 996_git_bundle ()
 997{
 998        local cmd="${COMP_WORDS[2]}"
 999        case "$COMP_CWORD" in
1000        2)
1001                __gitcomp "create list-heads verify unbundle"
1002                ;;
1003        3)
1004                # looking for a file
1005                ;;
1006        *)
1007                case "$cmd" in
1008                        create)
1009                                __git_complete_revlist
1010                        ;;
1011                esac
1012                ;;
1013        esac
1014}
1015
1016_git_checkout ()
1017{
1018        __git_has_doubledash && return
1019
1020        local cur="${COMP_WORDS[COMP_CWORD]}"
1021        case "$cur" in
1022        --conflict=*)
1023                __gitcomp "diff3 merge" "" "${cur##--conflict=}"
1024                ;;
1025        --*)
1026                __gitcomp "
1027                        --quiet --ours --theirs --track --no-track --merge
1028                        --conflict= --orphan --patch
1029                        "
1030                ;;
1031        *)
1032                # check if --track, --no-track, or --no-guess was specified
1033                # if so, disable DWIM mode
1034                local flags="--track --no-track --no-guess" track=1
1035                if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
1036                        track=''
1037                fi
1038                __gitcomp "$(__git_refs '' $track)"
1039                ;;
1040        esac
1041}
1042
1043_git_cherry ()
1044{
1045        __gitcomp "$(__git_refs)"
1046}
1047
1048_git_cherry_pick ()
1049{
1050        local cur="${COMP_WORDS[COMP_CWORD]}"
1051        case "$cur" in
1052        --*)
1053                __gitcomp "--edit --no-commit"
1054                ;;
1055        *)
1056                __gitcomp "$(__git_refs)"
1057                ;;
1058        esac
1059}
1060
1061_git_clean ()
1062{
1063        __git_has_doubledash && return
1064
1065        local cur="${COMP_WORDS[COMP_CWORD]}"
1066        case "$cur" in
1067        --*)
1068                __gitcomp "--dry-run --quiet"
1069                return
1070                ;;
1071        esac
1072        COMPREPLY=()
1073}
1074
1075_git_clone ()
1076{
1077        local cur="${COMP_WORDS[COMP_CWORD]}"
1078        case "$cur" in
1079        --*)
1080                __gitcomp "
1081                        --local
1082                        --no-hardlinks
1083                        --shared
1084                        --reference
1085                        --quiet
1086                        --no-checkout
1087                        --bare
1088                        --mirror
1089                        --origin
1090                        --upload-pack
1091                        --template=
1092                        --depth
1093                        "
1094                return
1095                ;;
1096        esac
1097        COMPREPLY=()
1098}
1099
1100_git_commit ()
1101{
1102        __git_has_doubledash && return
1103
1104        local cur="${COMP_WORDS[COMP_CWORD]}"
1105        case "$cur" in
1106        --cleanup=*)
1107                __gitcomp "default strip verbatim whitespace
1108                        " "" "${cur##--cleanup=}"
1109                return
1110                ;;
1111        --reuse-message=*)
1112                __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
1113                return
1114                ;;
1115        --reedit-message=*)
1116                __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
1117                return
1118                ;;
1119        --untracked-files=*)
1120                __gitcomp "all no normal" "" "${cur##--untracked-files=}"
1121                return
1122                ;;
1123        --*)
1124                __gitcomp "
1125                        --all --author= --signoff --verify --no-verify
1126                        --edit --amend --include --only --interactive
1127                        --dry-run --reuse-message= --reedit-message=
1128                        --reset-author --file= --message= --template=
1129                        --cleanup= --untracked-files --untracked-files=
1130                        --verbose --quiet
1131                        "
1132                return
1133        esac
1134        COMPREPLY=()
1135}
1136
1137_git_describe ()
1138{
1139        local cur="${COMP_WORDS[COMP_CWORD]}"
1140        case "$cur" in
1141        --*)
1142                __gitcomp "
1143                        --all --tags --contains --abbrev= --candidates=
1144                        --exact-match --debug --long --match --always
1145                        "
1146                return
1147        esac
1148        __gitcomp "$(__git_refs)"
1149}
1150
1151__git_diff_common_options="--stat --numstat --shortstat --summary
1152                        --patch-with-stat --name-only --name-status --color
1153                        --no-color --color-words --no-renames --check
1154                        --full-index --binary --abbrev --diff-filter=
1155                        --find-copies-harder
1156                        --text --ignore-space-at-eol --ignore-space-change
1157                        --ignore-all-space --exit-code --quiet --ext-diff
1158                        --no-ext-diff
1159                        --no-prefix --src-prefix= --dst-prefix=
1160                        --inter-hunk-context=
1161                        --patience
1162                        --raw
1163                        --dirstat --dirstat= --dirstat-by-file
1164                        --dirstat-by-file= --cumulative
1165"
1166
1167_git_diff ()
1168{
1169        __git_has_doubledash && return
1170
1171        local cur="${COMP_WORDS[COMP_CWORD]}"
1172        case "$cur" in
1173        --*)
1174                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1175                        --base --ours --theirs --no-index
1176                        $__git_diff_common_options
1177                        "
1178                return
1179                ;;
1180        esac
1181        __git_complete_file
1182}
1183
1184__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
1185                        tkdiff vimdiff gvimdiff xxdiff araxis p4merge
1186"
1187
1188_git_difftool ()
1189{
1190        __git_has_doubledash && return
1191
1192        local cur="${COMP_WORDS[COMP_CWORD]}"
1193        case "$cur" in
1194        --tool=*)
1195                __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
1196                return
1197                ;;
1198        --*)
1199                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1200                        --base --ours --theirs
1201                        --no-renames --diff-filter= --find-copies-harder
1202                        --relative --ignore-submodules
1203                        --tool="
1204                return
1205                ;;
1206        esac
1207        __git_complete_file
1208}
1209
1210__git_fetch_options="
1211        --quiet --verbose --append --upload-pack --force --keep --depth=
1212        --tags --no-tags --all --prune --dry-run
1213"
1214
1215_git_fetch ()
1216{
1217        local cur="${COMP_WORDS[COMP_CWORD]}"
1218        case "$cur" in
1219        --*)
1220                __gitcomp "$__git_fetch_options"
1221                return
1222                ;;
1223        esac
1224        __git_complete_remote_or_refspec
1225}
1226
1227_git_format_patch ()
1228{
1229        local cur="${COMP_WORDS[COMP_CWORD]}"
1230        case "$cur" in
1231        --thread=*)
1232                __gitcomp "
1233                        deep shallow
1234                        " "" "${cur##--thread=}"
1235                return
1236                ;;
1237        --*)
1238                __gitcomp "
1239                        --stdout --attach --no-attach --thread --thread=
1240                        --output-directory
1241                        --numbered --start-number
1242                        --numbered-files
1243                        --keep-subject
1244                        --signoff --signature --no-signature
1245                        --in-reply-to= --cc=
1246                        --full-index --binary
1247                        --not --all
1248                        --cover-letter
1249                        --no-prefix --src-prefix= --dst-prefix=
1250                        --inline --suffix= --ignore-if-in-upstream
1251                        --subject-prefix=
1252                        "
1253                return
1254                ;;
1255        esac
1256        __git_complete_revlist
1257}
1258
1259_git_fsck ()
1260{
1261        local cur="${COMP_WORDS[COMP_CWORD]}"
1262        case "$cur" in
1263        --*)
1264                __gitcomp "
1265                        --tags --root --unreachable --cache --no-reflogs --full
1266                        --strict --verbose --lost-found
1267                        "
1268                return
1269                ;;
1270        esac
1271        COMPREPLY=()
1272}
1273
1274_git_gc ()
1275{
1276        local cur="${COMP_WORDS[COMP_CWORD]}"
1277        case "$cur" in
1278        --*)
1279                __gitcomp "--prune --aggressive"
1280                return
1281                ;;
1282        esac
1283        COMPREPLY=()
1284}
1285
1286_git_gitk ()
1287{
1288        _gitk
1289}
1290
1291_git_grep ()
1292{
1293        __git_has_doubledash && return
1294
1295        local cur="${COMP_WORDS[COMP_CWORD]}"
1296        case "$cur" in
1297        --*)
1298                __gitcomp "
1299                        --cached
1300                        --text --ignore-case --word-regexp --invert-match
1301                        --full-name
1302                        --extended-regexp --basic-regexp --fixed-strings
1303                        --files-with-matches --name-only
1304                        --files-without-match
1305                        --max-depth
1306                        --count
1307                        --and --or --not --all-match
1308                        "
1309                return
1310                ;;
1311        esac
1312
1313        __gitcomp "$(__git_refs)"
1314}
1315
1316_git_help ()
1317{
1318        local cur="${COMP_WORDS[COMP_CWORD]}"
1319        case "$cur" in
1320        --*)
1321                __gitcomp "--all --info --man --web"
1322                return
1323                ;;
1324        esac
1325        __git_compute_all_commands
1326        __gitcomp "$__git_all_commands
1327                attributes cli core-tutorial cvs-migration
1328                diffcore gitk glossary hooks ignore modules
1329                repository-layout tutorial tutorial-2
1330                workflows
1331                "
1332}
1333
1334_git_init ()
1335{
1336        local cur="${COMP_WORDS[COMP_CWORD]}"
1337        case "$cur" in
1338        --shared=*)
1339                __gitcomp "
1340                        false true umask group all world everybody
1341                        " "" "${cur##--shared=}"
1342                return
1343                ;;
1344        --*)
1345                __gitcomp "--quiet --bare --template= --shared --shared="
1346                return
1347                ;;
1348        esac
1349        COMPREPLY=()
1350}
1351
1352_git_ls_files ()
1353{
1354        __git_has_doubledash && return
1355
1356        local cur="${COMP_WORDS[COMP_CWORD]}"
1357        case "$cur" in
1358        --*)
1359                __gitcomp "--cached --deleted --modified --others --ignored
1360                        --stage --directory --no-empty-directory --unmerged
1361                        --killed --exclude= --exclude-from=
1362                        --exclude-per-directory= --exclude-standard
1363                        --error-unmatch --with-tree= --full-name
1364                        --abbrev --ignored --exclude-per-directory
1365                        "
1366                return
1367                ;;
1368        esac
1369        COMPREPLY=()
1370}
1371
1372_git_ls_remote ()
1373{
1374        __gitcomp "$(__git_remotes)"
1375}
1376
1377_git_ls_tree ()
1378{
1379        __git_complete_file
1380}
1381
1382# Options that go well for log, shortlog and gitk
1383__git_log_common_options="
1384        --not --all
1385        --branches --tags --remotes
1386        --first-parent --merges --no-merges
1387        --max-count=
1388        --max-age= --since= --after=
1389        --min-age= --until= --before=
1390"
1391# Options that go well for log and gitk (not shortlog)
1392__git_log_gitk_options="
1393        --dense --sparse --full-history
1394        --simplify-merges --simplify-by-decoration
1395        --left-right
1396"
1397# Options that go well for log and shortlog (not gitk)
1398__git_log_shortlog_options="
1399        --author= --committer= --grep=
1400        --all-match
1401"
1402
1403__git_log_pretty_formats="oneline short medium full fuller email raw format:"
1404__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1405
1406_git_log ()
1407{
1408        __git_has_doubledash && return
1409
1410        local cur="${COMP_WORDS[COMP_CWORD]}"
1411        local g="$(git rev-parse --git-dir 2>/dev/null)"
1412        local merge=""
1413        if [ -f "$g/MERGE_HEAD" ]; then
1414                merge="--merge"
1415        fi
1416        case "$cur" in
1417        --pretty=*)
1418                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
1419                        " "" "${cur##--pretty=}"
1420                return
1421                ;;
1422        --format=*)
1423                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
1424                        " "" "${cur##--format=}"
1425                return
1426                ;;
1427        --date=*)
1428                __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1429                return
1430                ;;
1431        --decorate=*)
1432                __gitcomp "long short" "" "${cur##--decorate=}"
1433                return
1434                ;;
1435        --*)
1436                __gitcomp "
1437                        $__git_log_common_options
1438                        $__git_log_shortlog_options
1439                        $__git_log_gitk_options
1440                        --root --topo-order --date-order --reverse
1441                        --follow --full-diff
1442                        --abbrev-commit --abbrev=
1443                        --relative-date --date=
1444                        --pretty= --format= --oneline
1445                        --cherry-pick
1446                        --graph
1447                        --decorate --decorate=
1448                        --walk-reflogs
1449                        --parents --children
1450                        $merge
1451                        $__git_diff_common_options
1452                        --pickaxe-all --pickaxe-regex
1453                        "
1454                return
1455                ;;
1456        esac
1457        __git_complete_revlist
1458}
1459
1460__git_merge_options="
1461        --no-commit --no-stat --log --no-log --squash --strategy
1462        --commit --stat --no-squash --ff --no-ff --ff-only
1463"
1464
1465_git_merge ()
1466{
1467        __git_complete_strategy && return
1468
1469        local cur="${COMP_WORDS[COMP_CWORD]}"
1470        case "$cur" in
1471        --*)
1472                __gitcomp "$__git_merge_options"
1473                return
1474        esac
1475        __gitcomp "$(__git_refs)"
1476}
1477
1478_git_mergetool ()
1479{
1480        local cur="${COMP_WORDS[COMP_CWORD]}"
1481        case "$cur" in
1482        --tool=*)
1483                __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1484                return
1485                ;;
1486        --*)
1487                __gitcomp "--tool="
1488                return
1489                ;;
1490        esac
1491        COMPREPLY=()
1492}
1493
1494_git_merge_base ()
1495{
1496        __gitcomp "$(__git_refs)"
1497}
1498
1499_git_mv ()
1500{
1501        local cur="${COMP_WORDS[COMP_CWORD]}"
1502        case "$cur" in
1503        --*)
1504                __gitcomp "--dry-run"
1505                return
1506                ;;
1507        esac
1508        COMPREPLY=()
1509}
1510
1511_git_name_rev ()
1512{
1513        __gitcomp "--tags --all --stdin"
1514}
1515
1516_git_notes ()
1517{
1518        local subcommands='add append copy edit list prune remove show'
1519        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1520        local cur="${COMP_WORDS[COMP_CWORD]}"
1521
1522        case "$subcommand,$cur" in
1523        ,--*)
1524                __gitcomp '--ref'
1525                ;;
1526        ,*)
1527                case "${COMP_WORDS[COMP_CWORD-1]}" in
1528                --ref)
1529                        __gitcomp "$(__git_refs)"
1530                        ;;
1531                *)
1532                        __gitcomp "$subcommands --ref"
1533                        ;;
1534                esac
1535                ;;
1536        add,--reuse-message=*|append,--reuse-message=*)
1537                __gitcomp "$(__git_refs)" "" "${cur##--reuse-message=}"
1538                ;;
1539        add,--reedit-message=*|append,--reedit-message=*)
1540                __gitcomp "$(__git_refs)" "" "${cur##--reedit-message=}"
1541                ;;
1542        add,--*|append,--*)
1543                __gitcomp '--file= --message= --reedit-message=
1544                                --reuse-message='
1545                ;;
1546        copy,--*)
1547                __gitcomp '--stdin'
1548                ;;
1549        prune,--*)
1550                __gitcomp '--dry-run --verbose'
1551                ;;
1552        prune,*)
1553                ;;
1554        *)
1555                case "${COMP_WORDS[COMP_CWORD-1]}" in
1556                -m|-F)
1557                        ;;
1558                *)
1559                        __gitcomp "$(__git_refs)"
1560                        ;;
1561                esac
1562                ;;
1563        esac
1564}
1565
1566_git_pull ()
1567{
1568        __git_complete_strategy && return
1569
1570        local cur="${COMP_WORDS[COMP_CWORD]}"
1571        case "$cur" in
1572        --*)
1573                __gitcomp "
1574                        --rebase --no-rebase
1575                        $__git_merge_options
1576                        $__git_fetch_options
1577                "
1578                return
1579                ;;
1580        esac
1581        __git_complete_remote_or_refspec
1582}
1583
1584_git_push ()
1585{
1586        local cur="${COMP_WORDS[COMP_CWORD]}"
1587        case "${COMP_WORDS[COMP_CWORD-1]}" in
1588        --repo)
1589                __gitcomp "$(__git_remotes)"
1590                return
1591        esac
1592        case "$cur" in
1593        --repo=*)
1594                __gitcomp "$(__git_remotes)" "" "${cur##--repo=}"
1595                return
1596                ;;
1597        --*)
1598                __gitcomp "
1599                        --all --mirror --tags --dry-run --force --verbose
1600                        --receive-pack= --repo=
1601                "
1602                return
1603                ;;
1604        esac
1605        __git_complete_remote_or_refspec
1606}
1607
1608_git_rebase ()
1609{
1610        local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
1611        if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1612                __gitcomp "--continue --skip --abort"
1613                return
1614        fi
1615        __git_complete_strategy && return
1616        case "$cur" in
1617        --whitespace=*)
1618                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1619                return
1620                ;;
1621        --*)
1622                __gitcomp "
1623                        --onto --merge --strategy --interactive
1624                        --preserve-merges --stat --no-stat
1625                        --committer-date-is-author-date --ignore-date
1626                        --ignore-whitespace --whitespace=
1627                        --autosquash
1628                        "
1629
1630                return
1631        esac
1632        __gitcomp "$(__git_refs)"
1633}
1634
1635__git_send_email_confirm_options="always never auto cc compose"
1636__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1637
1638_git_send_email ()
1639{
1640        local cur="${COMP_WORDS[COMP_CWORD]}"
1641        case "$cur" in
1642        --confirm=*)
1643                __gitcomp "
1644                        $__git_send_email_confirm_options
1645                        " "" "${cur##--confirm=}"
1646                return
1647                ;;
1648        --suppress-cc=*)
1649                __gitcomp "
1650                        $__git_send_email_suppresscc_options
1651                        " "" "${cur##--suppress-cc=}"
1652
1653                return
1654                ;;
1655        --smtp-encryption=*)
1656                __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
1657                return
1658                ;;
1659        --*)
1660                __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1661                        --compose --confirm= --dry-run --envelope-sender
1662                        --from --identity
1663                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1664                        --no-suppress-from --no-thread --quiet
1665                        --signed-off-by-cc --smtp-pass --smtp-server
1666                        --smtp-server-port --smtp-encryption= --smtp-user
1667                        --subject --suppress-cc= --suppress-from --thread --to
1668                        --validate --no-validate"
1669                return
1670                ;;
1671        esac
1672        COMPREPLY=()
1673}
1674
1675_git_stage ()
1676{
1677        _git_add
1678}
1679
1680__git_config_get_set_variables ()
1681{
1682        local prevword word config_file= c=$COMP_CWORD
1683        while [ $c -gt 1 ]; do
1684                word="${COMP_WORDS[c]}"
1685                case "$word" in
1686                --global|--system|--file=*)
1687                        config_file="$word"
1688                        break
1689                        ;;
1690                -f|--file)
1691                        config_file="$word $prevword"
1692                        break
1693                        ;;
1694                esac
1695                prevword=$word
1696                c=$((--c))
1697        done
1698
1699        git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1700        while read line
1701        do
1702                case "$line" in
1703                *.*=*)
1704                        echo "${line/=*/}"
1705                        ;;
1706                esac
1707        done
1708}
1709
1710_git_config ()
1711{
1712        local cur="${COMP_WORDS[COMP_CWORD]}"
1713        local prv="${COMP_WORDS[COMP_CWORD-1]}"
1714        case "$prv" in
1715        branch.*.remote)
1716                __gitcomp "$(__git_remotes)"
1717                return
1718                ;;
1719        branch.*.merge)
1720                __gitcomp "$(__git_refs)"
1721                return
1722                ;;
1723        remote.*.fetch)
1724                local remote="${prv#remote.}"
1725                remote="${remote%.fetch}"
1726                __gitcomp "$(__git_refs_remotes "$remote")"
1727                return
1728                ;;
1729        remote.*.push)
1730                local remote="${prv#remote.}"
1731                remote="${remote%.push}"
1732                __gitcomp "$(git --git-dir="$(__gitdir)" \
1733                        for-each-ref --format='%(refname):%(refname)' \
1734                        refs/heads)"
1735                return
1736                ;;
1737        pull.twohead|pull.octopus)
1738                __git_compute_merge_strategies
1739                __gitcomp "$__git_merge_strategies"
1740                return
1741                ;;
1742        color.branch|color.diff|color.interactive|\
1743        color.showbranch|color.status|color.ui)
1744                __gitcomp "always never auto"
1745                return
1746                ;;
1747        color.pager)
1748                __gitcomp "false true"
1749                return
1750                ;;
1751        color.*.*)
1752                __gitcomp "
1753                        normal black red green yellow blue magenta cyan white
1754                        bold dim ul blink reverse
1755                        "
1756                return
1757                ;;
1758        help.format)
1759                __gitcomp "man info web html"
1760                return
1761                ;;
1762        log.date)
1763                __gitcomp "$__git_log_date_formats"
1764                return
1765                ;;
1766        sendemail.aliasesfiletype)
1767                __gitcomp "mutt mailrc pine elm gnus"
1768                return
1769                ;;
1770        sendemail.confirm)
1771                __gitcomp "$__git_send_email_confirm_options"
1772                return
1773                ;;
1774        sendemail.suppresscc)
1775                __gitcomp "$__git_send_email_suppresscc_options"
1776                return
1777                ;;
1778        --get|--get-all|--unset|--unset-all)
1779                __gitcomp "$(__git_config_get_set_variables)"
1780                return
1781                ;;
1782        *.*)
1783                COMPREPLY=()
1784                return
1785                ;;
1786        esac
1787        case "$cur" in
1788        --*)
1789                __gitcomp "
1790                        --global --system --file=
1791                        --list --replace-all
1792                        --get --get-all --get-regexp
1793                        --add --unset --unset-all
1794                        --remove-section --rename-section
1795                        "
1796                return
1797                ;;
1798        branch.*.*)
1799                local pfx="${cur%.*}."
1800                cur="${cur##*.}"
1801                __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur"
1802                return
1803                ;;
1804        branch.*)
1805                local pfx="${cur%.*}."
1806                cur="${cur#*.}"
1807                __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1808                return
1809                ;;
1810        guitool.*.*)
1811                local pfx="${cur%.*}."
1812                cur="${cur##*.}"
1813                __gitcomp "
1814                        argprompt cmd confirm needsfile noconsole norescan
1815                        prompt revprompt revunmerged title
1816                        " "$pfx" "$cur"
1817                return
1818                ;;
1819        difftool.*.*)
1820                local pfx="${cur%.*}."
1821                cur="${cur##*.}"
1822                __gitcomp "cmd path" "$pfx" "$cur"
1823                return
1824                ;;
1825        man.*.*)
1826                local pfx="${cur%.*}."
1827                cur="${cur##*.}"
1828                __gitcomp "cmd path" "$pfx" "$cur"
1829                return
1830                ;;
1831        mergetool.*.*)
1832                local pfx="${cur%.*}."
1833                cur="${cur##*.}"
1834                __gitcomp "cmd path trustExitCode" "$pfx" "$cur"
1835                return
1836                ;;
1837        pager.*)
1838                local pfx="${cur%.*}."
1839                cur="${cur#*.}"
1840                __git_compute_all_commands
1841                __gitcomp "$__git_all_commands" "$pfx" "$cur"
1842                return
1843                ;;
1844        remote.*.*)
1845                local pfx="${cur%.*}."
1846                cur="${cur##*.}"
1847                __gitcomp "
1848                        url proxy fetch push mirror skipDefaultUpdate
1849                        receivepack uploadpack tagopt pushurl
1850                        " "$pfx" "$cur"
1851                return
1852                ;;
1853        remote.*)
1854                local pfx="${cur%.*}."
1855                cur="${cur#*.}"
1856                __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1857                return
1858                ;;
1859        url.*.*)
1860                local pfx="${cur%.*}."
1861                cur="${cur##*.}"
1862                __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur"
1863                return
1864                ;;
1865        esac
1866        __gitcomp "
1867                add.ignore-errors
1868                alias.
1869                apply.ignorewhitespace
1870                apply.whitespace
1871                branch.autosetupmerge
1872                branch.autosetuprebase
1873                clean.requireForce
1874                color.branch
1875                color.branch.current
1876                color.branch.local
1877                color.branch.plain
1878                color.branch.remote
1879                color.diff
1880                color.diff.commit
1881                color.diff.frag
1882                color.diff.meta
1883                color.diff.new
1884                color.diff.old
1885                color.diff.plain
1886                color.diff.whitespace
1887                color.grep
1888                color.grep.external
1889                color.grep.match
1890                color.interactive
1891                color.interactive.header
1892                color.interactive.help
1893                color.interactive.prompt
1894                color.pager
1895                color.showbranch
1896                color.status
1897                color.status.added
1898                color.status.changed
1899                color.status.header
1900                color.status.nobranch
1901                color.status.untracked
1902                color.status.updated
1903                color.ui
1904                commit.template
1905                core.autocrlf
1906                core.bare
1907                core.compression
1908                core.createObject
1909                core.deltaBaseCacheLimit
1910                core.editor
1911                core.excludesfile
1912                core.fileMode
1913                core.fsyncobjectfiles
1914                core.gitProxy
1915                core.ignoreCygwinFSTricks
1916                core.ignoreStat
1917                core.logAllRefUpdates
1918                core.loosecompression
1919                core.packedGitLimit
1920                core.packedGitWindowSize
1921                core.pager
1922                core.preferSymlinkRefs
1923                core.preloadindex
1924                core.quotepath
1925                core.repositoryFormatVersion
1926                core.safecrlf
1927                core.sharedRepository
1928                core.symlinks
1929                core.trustctime
1930                core.warnAmbiguousRefs
1931                core.whitespace
1932                core.worktree
1933                diff.autorefreshindex
1934                diff.external
1935                diff.mnemonicprefix
1936                diff.renameLimit
1937                diff.renameLimit.
1938                diff.renames
1939                diff.suppressBlankEmpty
1940                diff.tool
1941                diff.wordRegex
1942                difftool.
1943                difftool.prompt
1944                fetch.unpackLimit
1945                format.attach
1946                format.cc
1947                format.headers
1948                format.numbered
1949                format.pretty
1950                format.signature
1951                format.signoff
1952                format.subjectprefix
1953                format.suffix
1954                format.thread
1955                gc.aggressiveWindow
1956                gc.auto
1957                gc.autopacklimit
1958                gc.packrefs
1959                gc.pruneexpire
1960                gc.reflogexpire
1961                gc.reflogexpireunreachable
1962                gc.rerereresolved
1963                gc.rerereunresolved
1964                gitcvs.allbinary
1965                gitcvs.commitmsgannotation
1966                gitcvs.dbTableNamePrefix
1967                gitcvs.dbdriver
1968                gitcvs.dbname
1969                gitcvs.dbpass
1970                gitcvs.dbuser
1971                gitcvs.enabled
1972                gitcvs.logfile
1973                gitcvs.usecrlfattr
1974                guitool.
1975                gui.blamehistoryctx
1976                gui.commitmsgwidth
1977                gui.copyblamethreshold
1978                gui.diffcontext
1979                gui.encoding
1980                gui.fastcopyblame
1981                gui.matchtrackingbranch
1982                gui.newbranchtemplate
1983                gui.pruneduringfetch
1984                gui.spellingdictionary
1985                gui.trustmtime
1986                help.autocorrect
1987                help.browser
1988                help.format
1989                http.lowSpeedLimit
1990                http.lowSpeedTime
1991                http.maxRequests
1992                http.noEPSV
1993                http.proxy
1994                http.sslCAInfo
1995                http.sslCAPath
1996                http.sslCert
1997                http.sslKey
1998                http.sslVerify
1999                i18n.commitEncoding
2000                i18n.logOutputEncoding
2001                imap.folder
2002                imap.host
2003                imap.pass
2004                imap.port
2005                imap.preformattedHTML
2006                imap.sslverify
2007                imap.tunnel
2008                imap.user
2009                instaweb.browser
2010                instaweb.httpd
2011                instaweb.local
2012                instaweb.modulepath
2013                instaweb.port
2014                interactive.singlekey
2015                log.date
2016                log.showroot
2017                mailmap.file
2018                man.
2019                man.viewer
2020                merge.conflictstyle
2021                merge.log
2022                merge.renameLimit
2023                merge.stat
2024                merge.tool
2025                merge.verbosity
2026                mergetool.
2027                mergetool.keepBackup
2028                mergetool.prompt
2029                pack.compression
2030                pack.deltaCacheLimit
2031                pack.deltaCacheSize
2032                pack.depth
2033                pack.indexVersion
2034                pack.packSizeLimit
2035                pack.threads
2036                pack.window
2037                pack.windowMemory
2038                pager.
2039                pull.octopus
2040                pull.twohead
2041                push.default
2042                rebase.stat
2043                receive.denyCurrentBranch
2044                receive.denyDeletes
2045                receive.denyNonFastForwards
2046                receive.fsckObjects
2047                receive.unpackLimit
2048                repack.usedeltabaseoffset
2049                rerere.autoupdate
2050                rerere.enabled
2051                sendemail.aliasesfile
2052                sendemail.aliasesfiletype
2053                sendemail.bcc
2054                sendemail.cc
2055                sendemail.cccmd
2056                sendemail.chainreplyto
2057                sendemail.confirm
2058                sendemail.envelopesender
2059                sendemail.multiedit
2060                sendemail.signedoffbycc
2061                sendemail.smtpencryption
2062                sendemail.smtppass
2063                sendemail.smtpserver
2064                sendemail.smtpserverport
2065                sendemail.smtpuser
2066                sendemail.suppresscc
2067                sendemail.suppressfrom
2068                sendemail.thread
2069                sendemail.to
2070                sendemail.validate
2071                showbranch.default
2072                status.relativePaths
2073                status.showUntrackedFiles
2074                tar.umask
2075                transfer.unpackLimit
2076                url.
2077                user.email
2078                user.name
2079                user.signingkey
2080                web.browser
2081                branch. remote.
2082        "
2083}
2084
2085_git_remote ()
2086{
2087        local subcommands="add rename rm show prune update set-head"
2088        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2089        if [ -z "$subcommand" ]; then
2090                __gitcomp "$subcommands"
2091                return
2092        fi
2093
2094        case "$subcommand" in
2095        rename|rm|show|prune)
2096                __gitcomp "$(__git_remotes)"
2097                ;;
2098        update)
2099                local i c='' IFS=$'\n'
2100                for i in $(git --git-dir="$(__gitdir)" config --get-regexp "remotes\..*" 2>/dev/null); do
2101                        i="${i#remotes.}"
2102                        c="$c ${i/ */}"
2103                done
2104                __gitcomp "$c"
2105                ;;
2106        *)
2107                COMPREPLY=()
2108                ;;
2109        esac
2110}
2111
2112_git_replace ()
2113{
2114        __gitcomp "$(__git_refs)"
2115}
2116
2117_git_reset ()
2118{
2119        __git_has_doubledash && return
2120
2121        local cur="${COMP_WORDS[COMP_CWORD]}"
2122        case "$cur" in
2123        --*)
2124                __gitcomp "--merge --mixed --hard --soft --patch"
2125                return
2126                ;;
2127        esac
2128        __gitcomp "$(__git_refs)"
2129}
2130
2131_git_revert ()
2132{
2133        local cur="${COMP_WORDS[COMP_CWORD]}"
2134        case "$cur" in
2135        --*)
2136                __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
2137                return
2138                ;;
2139        esac
2140        __gitcomp "$(__git_refs)"
2141}
2142
2143_git_rm ()
2144{
2145        __git_has_doubledash && return
2146
2147        local cur="${COMP_WORDS[COMP_CWORD]}"
2148        case "$cur" in
2149        --*)
2150                __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
2151                return
2152                ;;
2153        esac
2154        COMPREPLY=()
2155}
2156
2157_git_shortlog ()
2158{
2159        __git_has_doubledash && return
2160
2161        local cur="${COMP_WORDS[COMP_CWORD]}"
2162        case "$cur" in
2163        --*)
2164                __gitcomp "
2165                        $__git_log_common_options
2166                        $__git_log_shortlog_options
2167                        --numbered --summary
2168                        "
2169                return
2170                ;;
2171        esac
2172        __git_complete_revlist
2173}
2174
2175_git_show ()
2176{
2177        __git_has_doubledash && return
2178
2179        local cur="${COMP_WORDS[COMP_CWORD]}"
2180        case "$cur" in
2181        --pretty=*)
2182                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
2183                        " "" "${cur##--pretty=}"
2184                return
2185                ;;
2186        --format=*)
2187                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
2188                        " "" "${cur##--format=}"
2189                return
2190                ;;
2191        --*)
2192                __gitcomp "--pretty= --format= --abbrev-commit --oneline
2193                        $__git_diff_common_options
2194                        "
2195                return
2196                ;;
2197        esac
2198        __git_complete_file
2199}
2200
2201_git_show_branch ()
2202{
2203        local cur="${COMP_WORDS[COMP_CWORD]}"
2204        case "$cur" in
2205        --*)
2206                __gitcomp "
2207                        --all --remotes --topo-order --current --more=
2208                        --list --independent --merge-base --no-name
2209                        --color --no-color
2210                        --sha1-name --sparse --topics --reflog
2211                        "
2212                return
2213                ;;
2214        esac
2215        __git_complete_revlist
2216}
2217
2218_git_stash ()
2219{
2220        local cur="${COMP_WORDS[COMP_CWORD]}"
2221        local save_opts='--keep-index --no-keep-index --quiet --patch'
2222        local subcommands='save list show apply clear drop pop create branch'
2223        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2224        if [ -z "$subcommand" ]; then
2225                case "$cur" in
2226                --*)
2227                        __gitcomp "$save_opts"
2228                        ;;
2229                *)
2230                        if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
2231                                __gitcomp "$subcommands"
2232                        else
2233                                COMPREPLY=()
2234                        fi
2235                        ;;
2236                esac
2237        else
2238                case "$subcommand,$cur" in
2239                save,--*)
2240                        __gitcomp "$save_opts"
2241                        ;;
2242                apply,--*|pop,--*)
2243                        __gitcomp "--index --quiet"
2244                        ;;
2245                show,--*|drop,--*|branch,--*)
2246                        COMPREPLY=()
2247                        ;;
2248                show,*|apply,*|drop,*|pop,*|branch,*)
2249                        __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
2250                                        | sed -n -e 's/:.*//p')"
2251                        ;;
2252                *)
2253                        COMPREPLY=()
2254                        ;;
2255                esac
2256        fi
2257}
2258
2259_git_submodule ()
2260{
2261        __git_has_doubledash && return
2262
2263        local subcommands="add status init update summary foreach sync"
2264        if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
2265                local cur="${COMP_WORDS[COMP_CWORD]}"
2266                case "$cur" in
2267                --*)
2268                        __gitcomp "--quiet --cached"
2269                        ;;
2270                *)
2271                        __gitcomp "$subcommands"
2272                        ;;
2273                esac
2274                return
2275        fi
2276}
2277
2278_git_svn ()
2279{
2280        local subcommands="
2281                init fetch clone rebase dcommit log find-rev
2282                set-tree commit-diff info create-ignore propget
2283                proplist show-ignore show-externals branch tag blame
2284                migrate mkdirs reset gc
2285                "
2286        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2287        if [ -z "$subcommand" ]; then
2288                __gitcomp "$subcommands"
2289        else
2290                local remote_opts="--username= --config-dir= --no-auth-cache"
2291                local fc_opts="
2292                        --follow-parent --authors-file= --repack=
2293                        --no-metadata --use-svm-props --use-svnsync-props
2294                        --log-window-size= --no-checkout --quiet
2295                        --repack-flags --use-log-author --localtime
2296                        --ignore-paths= $remote_opts
2297                        "
2298                local init_opts="
2299                        --template= --shared= --trunk= --tags=
2300                        --branches= --stdlayout --minimize-url
2301                        --no-metadata --use-svm-props --use-svnsync-props
2302                        --rewrite-root= --prefix= --use-log-author
2303                        --add-author-from $remote_opts
2304                        "
2305                local cmt_opts="
2306                        --edit --rmdir --find-copies-harder --copy-similarity=
2307                        "
2308
2309                local cur="${COMP_WORDS[COMP_CWORD]}"
2310                case "$subcommand,$cur" in
2311                fetch,--*)
2312                        __gitcomp "--revision= --fetch-all $fc_opts"
2313                        ;;
2314                clone,--*)
2315                        __gitcomp "--revision= $fc_opts $init_opts"
2316                        ;;
2317                init,--*)
2318                        __gitcomp "$init_opts"
2319                        ;;
2320                dcommit,--*)
2321                        __gitcomp "
2322                                --merge --strategy= --verbose --dry-run
2323                                --fetch-all --no-rebase --commit-url
2324                                --revision $cmt_opts $fc_opts
2325                                "
2326                        ;;
2327                set-tree,--*)
2328                        __gitcomp "--stdin $cmt_opts $fc_opts"
2329                        ;;
2330                create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
2331                show-externals,--*|mkdirs,--*)
2332                        __gitcomp "--revision="
2333                        ;;
2334                log,--*)
2335                        __gitcomp "
2336                                --limit= --revision= --verbose --incremental
2337                                --oneline --show-commit --non-recursive
2338                                --authors-file= --color
2339                                "
2340                        ;;
2341                rebase,--*)
2342                        __gitcomp "
2343                                --merge --verbose --strategy= --local
2344                                --fetch-all --dry-run $fc_opts
2345                                "
2346                        ;;
2347                commit-diff,--*)
2348                        __gitcomp "--message= --file= --revision= $cmt_opts"
2349                        ;;
2350                info,--*)
2351                        __gitcomp "--url"
2352                        ;;
2353                branch,--*)
2354                        __gitcomp "--dry-run --message --tag"
2355                        ;;
2356                tag,--*)
2357                        __gitcomp "--dry-run --message"
2358                        ;;
2359                blame,--*)
2360                        __gitcomp "--git-format"
2361                        ;;
2362                migrate,--*)
2363                        __gitcomp "
2364                                --config-dir= --ignore-paths= --minimize
2365                                --no-auth-cache --username=
2366                                "
2367                        ;;
2368                reset,--*)
2369                        __gitcomp "--revision= --parent"
2370                        ;;
2371                *)
2372                        COMPREPLY=()
2373                        ;;
2374                esac
2375        fi
2376}
2377
2378_git_tag ()
2379{
2380        local i c=1 f=0
2381        while [ $c -lt $COMP_CWORD ]; do
2382                i="${COMP_WORDS[c]}"
2383                case "$i" in
2384                -d|-v)
2385                        __gitcomp "$(__git_tags)"
2386                        return
2387                        ;;
2388                -f)
2389                        f=1
2390                        ;;
2391                esac
2392                c=$((++c))
2393        done
2394
2395        case "${COMP_WORDS[COMP_CWORD-1]}" in
2396        -m|-F)
2397                COMPREPLY=()
2398                ;;
2399        -*|tag)
2400                if [ $f = 1 ]; then
2401                        __gitcomp "$(__git_tags)"
2402                else
2403                        COMPREPLY=()
2404                fi
2405                ;;
2406        *)
2407                __gitcomp "$(__git_refs)"
2408                ;;
2409        esac
2410}
2411
2412_git_whatchanged ()
2413{
2414        _git_log
2415}
2416
2417_git ()
2418{
2419        local i c=1 command __git_dir
2420
2421        if [[ -n ${ZSH_VERSION-} ]]; then
2422                emulate -L bash
2423                setopt KSH_TYPESET
2424        fi
2425
2426        while [ $c -lt $COMP_CWORD ]; do
2427                i="${COMP_WORDS[c]}"
2428                case "$i" in
2429                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
2430                --bare)      __git_dir="." ;;
2431                --version|-p|--paginate) ;;
2432                --help) command="help"; break ;;
2433                *) command="$i"; break ;;
2434                esac
2435                c=$((++c))
2436        done
2437
2438        if [ -z "$command" ]; then
2439                case "${COMP_WORDS[COMP_CWORD]}" in
2440                --*)   __gitcomp "
2441                        --paginate
2442                        --no-pager
2443                        --git-dir=
2444                        --bare
2445                        --version
2446                        --exec-path
2447                        --html-path
2448                        --work-tree=
2449                        --help
2450                        "
2451                        ;;
2452                *)     __git_compute_porcelain_commands
2453                       __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2454                esac
2455                return
2456        fi
2457
2458        local completion_func="_git_${command//-/_}"
2459        declare -f $completion_func >/dev/null && $completion_func && return
2460
2461        local expansion=$(__git_aliased_command "$command")
2462        if [ -n "$expansion" ]; then
2463                completion_func="_git_${expansion//-/_}"
2464                declare -f $completion_func >/dev/null && $completion_func
2465        fi
2466}
2467
2468_gitk ()
2469{
2470        if [[ -n ${ZSH_VERSION-} ]]; then
2471                emulate -L bash
2472                setopt KSH_TYPESET
2473        fi
2474
2475        __git_has_doubledash && return
2476
2477        local cur="${COMP_WORDS[COMP_CWORD]}"
2478        local g="$(__gitdir)"
2479        local merge=""
2480        if [ -f "$g/MERGE_HEAD" ]; then
2481                merge="--merge"
2482        fi
2483        case "$cur" in
2484        --*)
2485                __gitcomp "
2486                        $__git_log_common_options
2487                        $__git_log_gitk_options
2488                        $merge
2489                        "
2490                return
2491                ;;
2492        esac
2493        __git_complete_revlist
2494}
2495
2496complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \
2497        || complete -o default -o nospace -F _git git
2498complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \
2499        || complete -o default -o nospace -F _gitk gitk
2500
2501# The following are necessary only for Cygwin, and only are needed
2502# when the user has tab-completed the executable name and consequently
2503# included the '.exe' suffix.
2504#
2505if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
2506complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
2507        || complete -o default -o nospace -F _git git.exe
2508fi
2509
2510if [[ -n ${ZSH_VERSION-} ]]; then
2511        shopt () {
2512                local option
2513                if [ $# -ne 2 ]; then
2514                        echo "USAGE: $0 (-q|-s|-u) <option>" >&2
2515                        return 1
2516                fi
2517                case "$2" in
2518                nullglob)
2519                        option="$2"
2520                        ;;
2521                *)
2522                        echo "$0: invalid option: $2" >&2
2523                        return 1
2524                esac
2525                case "$1" in
2526                -q)     setopt | grep -q "$option" ;;
2527                -u)     unsetopt "$option" ;;
2528                -s)     setopt "$option" ;;
2529                *)
2530                        echo "$0: invalid flag: $1" >&2
2531                        return 1
2532                esac
2533        }
2534fi