contrib / completion / git-completion.bashon commit Merge branch 'rs/use-strbuf-addbuf' (b4e8a84)
   1# bash/zsh completion support for core Git.
   2#
   3# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
   4# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
   5# Distributed under the GNU General Public License, version 2.0.
   6#
   7# The contained completion routines provide support for completing:
   8#
   9#    *) local and remote branch names
  10#    *) local and remote tag names
  11#    *) .git/remotes file names
  12#    *) git 'subcommands'
  13#    *) git email aliases for git-send-email
  14#    *) tree paths within 'ref:path/to/file' expressions
  15#    *) file paths within current working directory and index
  16#    *) common --long-options
  17#
  18# To use these routines:
  19#
  20#    1) Copy this file to somewhere (e.g. ~/.git-completion.bash).
  21#    2) Add the following line to your .bashrc/.zshrc:
  22#        source ~/.git-completion.bash
  23#    3) Consider changing your PS1 to also show the current branch,
  24#       see git-prompt.sh for details.
  25#
  26# If you use complex aliases of form '!f() { ... }; f', you can use the null
  27# command ':' as the first command in the function body to declare the desired
  28# completion style.  For example '!f() { : git commit ; ... }; f' will
  29# tell the completion to use commit completion.  This also works with aliases
  30# of form "!sh -c '...'".  For example, "!sh -c ': git commit ; ... '".
  31
  32case "$COMP_WORDBREAKS" in
  33*:*) : great ;;
  34*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
  35esac
  36
  37# __gitdir accepts 0 or 1 arguments (i.e., location)
  38# returns location of .git repo
  39__gitdir ()
  40{
  41        if [ -z "${1-}" ]; then
  42                if [ -n "${__git_dir-}" ]; then
  43                        echo "$__git_dir"
  44                elif [ -n "${GIT_DIR-}" ]; then
  45                        test -d "${GIT_DIR-}" || return 1
  46                        echo "$GIT_DIR"
  47                elif [ -d .git ]; then
  48                        echo .git
  49                else
  50                        git rev-parse --git-dir 2>/dev/null
  51                fi
  52        elif [ -d "$1/.git" ]; then
  53                echo "$1/.git"
  54        else
  55                echo "$1"
  56        fi
  57}
  58
  59# The following function is based on code from:
  60#
  61#   bash_completion - programmable completion functions for bash 3.2+
  62#
  63#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
  64#             © 2009-2010, Bash Completion Maintainers
  65#                     <bash-completion-devel@lists.alioth.debian.org>
  66#
  67#   This program is free software; you can redistribute it and/or modify
  68#   it under the terms of the GNU General Public License as published by
  69#   the Free Software Foundation; either version 2, or (at your option)
  70#   any later version.
  71#
  72#   This program is distributed in the hope that it will be useful,
  73#   but WITHOUT ANY WARRANTY; without even the implied warranty of
  74#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  75#   GNU General Public License for more details.
  76#
  77#   You should have received a copy of the GNU General Public License
  78#   along with this program; if not, write to the Free Software Foundation,
  79#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  80#
  81#   The latest version of this software can be obtained here:
  82#
  83#   http://bash-completion.alioth.debian.org/
  84#
  85#   RELEASE: 2.x
  86
  87# This function can be used to access a tokenized list of words
  88# on the command line:
  89#
  90#       __git_reassemble_comp_words_by_ref '=:'
  91#       if test "${words_[cword_-1]}" = -w
  92#       then
  93#               ...
  94#       fi
  95#
  96# The argument should be a collection of characters from the list of
  97# word completion separators (COMP_WORDBREAKS) to treat as ordinary
  98# characters.
  99#
 100# This is roughly equivalent to going back in time and setting
 101# COMP_WORDBREAKS to exclude those characters.  The intent is to
 102# make option types like --date=<type> and <rev>:<path> easy to
 103# recognize by treating each shell word as a single token.
 104#
 105# It is best not to set COMP_WORDBREAKS directly because the value is
 106# shared with other completion scripts.  By the time the completion
 107# function gets called, COMP_WORDS has already been populated so local
 108# changes to COMP_WORDBREAKS have no effect.
 109#
 110# Output: words_, cword_, cur_.
 111
 112__git_reassemble_comp_words_by_ref()
 113{
 114        local exclude i j first
 115        # Which word separators to exclude?
 116        exclude="${1//[^$COMP_WORDBREAKS]}"
 117        cword_=$COMP_CWORD
 118        if [ -z "$exclude" ]; then
 119                words_=("${COMP_WORDS[@]}")
 120                return
 121        fi
 122        # List of word completion separators has shrunk;
 123        # re-assemble words to complete.
 124        for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
 125                # Append each nonempty word consisting of just
 126                # word separator characters to the current word.
 127                first=t
 128                while
 129                        [ $i -gt 0 ] &&
 130                        [ -n "${COMP_WORDS[$i]}" ] &&
 131                        # word consists of excluded word separators
 132                        [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
 133                do
 134                        # Attach to the previous token,
 135                        # unless the previous token is the command name.
 136                        if [ $j -ge 2 ] && [ -n "$first" ]; then
 137                                ((j--))
 138                        fi
 139                        first=
 140                        words_[$j]=${words_[j]}${COMP_WORDS[i]}
 141                        if [ $i = $COMP_CWORD ]; then
 142                                cword_=$j
 143                        fi
 144                        if (($i < ${#COMP_WORDS[@]} - 1)); then
 145                                ((i++))
 146                        else
 147                                # Done.
 148                                return
 149                        fi
 150                done
 151                words_[$j]=${words_[j]}${COMP_WORDS[i]}
 152                if [ $i = $COMP_CWORD ]; then
 153                        cword_=$j
 154                fi
 155        done
 156}
 157
 158if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
 159_get_comp_words_by_ref ()
 160{
 161        local exclude cur_ words_ cword_
 162        if [ "$1" = "-n" ]; then
 163                exclude=$2
 164                shift 2
 165        fi
 166        __git_reassemble_comp_words_by_ref "$exclude"
 167        cur_=${words_[cword_]}
 168        while [ $# -gt 0 ]; do
 169                case "$1" in
 170                cur)
 171                        cur=$cur_
 172                        ;;
 173                prev)
 174                        prev=${words_[$cword_-1]}
 175                        ;;
 176                words)
 177                        words=("${words_[@]}")
 178                        ;;
 179                cword)
 180                        cword=$cword_
 181                        ;;
 182                esac
 183                shift
 184        done
 185}
 186fi
 187
 188__gitcompappend ()
 189{
 190        local x i=${#COMPREPLY[@]}
 191        for x in $1; do
 192                if [[ "$x" == "$3"* ]]; then
 193                        COMPREPLY[i++]="$2$x$4"
 194                fi
 195        done
 196}
 197
 198__gitcompadd ()
 199{
 200        COMPREPLY=()
 201        __gitcompappend "$@"
 202}
 203
 204# Generates completion reply, appending a space to possible completion words,
 205# if necessary.
 206# It accepts 1 to 4 arguments:
 207# 1: List of possible completion words.
 208# 2: A prefix to be added to each possible completion word (optional).
 209# 3: Generate possible completion matches for this word (optional).
 210# 4: A suffix to be appended to each possible completion word (optional).
 211__gitcomp ()
 212{
 213        local cur_="${3-$cur}"
 214
 215        case "$cur_" in
 216        --*=)
 217                ;;
 218        *)
 219                local c i=0 IFS=$' \t\n'
 220                for c in $1; do
 221                        c="$c${4-}"
 222                        if [[ $c == "$cur_"* ]]; then
 223                                case $c in
 224                                --*=*|*.) ;;
 225                                *) c="$c " ;;
 226                                esac
 227                                COMPREPLY[i++]="${2-}$c"
 228                        fi
 229                done
 230                ;;
 231        esac
 232}
 233
 234# Variation of __gitcomp_nl () that appends to the existing list of
 235# completion candidates, COMPREPLY.
 236__gitcomp_nl_append ()
 237{
 238        local IFS=$'\n'
 239        __gitcompappend "$1" "${2-}" "${3-$cur}" "${4- }"
 240}
 241
 242# Generates completion reply from newline-separated possible completion words
 243# by appending a space to all of them.
 244# It accepts 1 to 4 arguments:
 245# 1: List of possible completion words, separated by a single newline.
 246# 2: A prefix to be added to each possible completion word (optional).
 247# 3: Generate possible completion matches for this word (optional).
 248# 4: A suffix to be appended to each possible completion word instead of
 249#    the default space (optional).  If specified but empty, nothing is
 250#    appended.
 251__gitcomp_nl ()
 252{
 253        COMPREPLY=()
 254        __gitcomp_nl_append "$@"
 255}
 256
 257# Generates completion reply with compgen from newline-separated possible
 258# completion filenames.
 259# It accepts 1 to 3 arguments:
 260# 1: List of possible completion filenames, separated by a single newline.
 261# 2: A directory prefix to be added to each possible completion filename
 262#    (optional).
 263# 3: Generate possible completion matches for this word (optional).
 264__gitcomp_file ()
 265{
 266        local IFS=$'\n'
 267
 268        # XXX does not work when the directory prefix contains a tilde,
 269        # since tilde expansion is not applied.
 270        # This means that COMPREPLY will be empty and Bash default
 271        # completion will be used.
 272        __gitcompadd "$1" "${2-}" "${3-$cur}" ""
 273
 274        # use a hack to enable file mode in bash < 4
 275        compopt -o filenames +o nospace 2>/dev/null ||
 276        compgen -f /non-existing-dir/ > /dev/null
 277}
 278
 279# Execute 'git ls-files', unless the --committable option is specified, in
 280# which case it runs 'git diff-index' to find out the files that can be
 281# committed.  It return paths relative to the directory specified in the first
 282# argument, and using the options specified in the second argument.
 283__git_ls_files_helper ()
 284{
 285        if [ "$2" == "--committable" ]; then
 286                git -C "$1" diff-index --name-only --relative HEAD
 287        else
 288                # NOTE: $2 is not quoted in order to support multiple options
 289                git -C "$1" ls-files --exclude-standard $2
 290        fi 2>/dev/null
 291}
 292
 293
 294# __git_index_files accepts 1 or 2 arguments:
 295# 1: Options to pass to ls-files (required).
 296# 2: A directory path (optional).
 297#    If provided, only files within the specified directory are listed.
 298#    Sub directories are never recursed.  Path must have a trailing
 299#    slash.
 300__git_index_files ()
 301{
 302        local dir="$(__gitdir)" root="${2-.}" file
 303
 304        if [ -d "$dir" ]; then
 305                __git_ls_files_helper "$root" "$1" |
 306                while read -r file; do
 307                        case "$file" in
 308                        ?*/*) echo "${file%%/*}" ;;
 309                        *) echo "$file" ;;
 310                        esac
 311                done | sort | uniq
 312        fi
 313}
 314
 315__git_heads ()
 316{
 317        local dir="$(__gitdir)"
 318        if [ -d "$dir" ]; then
 319                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
 320                        refs/heads
 321                return
 322        fi
 323}
 324
 325__git_tags ()
 326{
 327        local dir="$(__gitdir)"
 328        if [ -d "$dir" ]; then
 329                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
 330                        refs/tags
 331                return
 332        fi
 333}
 334
 335# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
 336# presence of 2nd argument means use the guess heuristic employed
 337# by checkout for tracking branches
 338__git_refs ()
 339{
 340        local i hash dir="$(__gitdir "${1-}")" track="${2-}"
 341        local format refs
 342        if [ -d "$dir" ]; then
 343                case "$cur" in
 344                refs|refs/*)
 345                        format="refname"
 346                        refs="${cur%/*}"
 347                        track=""
 348                        ;;
 349                *)
 350                        for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
 351                                if [ -e "$dir/$i" ]; then echo $i; fi
 352                        done
 353                        format="refname:short"
 354                        refs="refs/tags refs/heads refs/remotes"
 355                        ;;
 356                esac
 357                git --git-dir="$dir" for-each-ref --format="%($format)" \
 358                        $refs
 359                if [ -n "$track" ]; then
 360                        # employ the heuristic used by git checkout
 361                        # Try to find a remote branch that matches the completion word
 362                        # but only output if the branch name is unique
 363                        local ref entry
 364                        git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \
 365                                "refs/remotes/" | \
 366                        while read -r entry; do
 367                                eval "$entry"
 368                                ref="${ref#*/}"
 369                                if [[ "$ref" == "$cur"* ]]; then
 370                                        echo "$ref"
 371                                fi
 372                        done | sort | uniq -u
 373                fi
 374                return
 375        fi
 376        case "$cur" in
 377        refs|refs/*)
 378                git ls-remote "$dir" "$cur*" 2>/dev/null | \
 379                while read -r hash i; do
 380                        case "$i" in
 381                        *^{}) ;;
 382                        *) echo "$i" ;;
 383                        esac
 384                done
 385                ;;
 386        *)
 387                echo "HEAD"
 388                git for-each-ref --format="%(refname:short)" -- \
 389                        "refs/remotes/$dir/" 2>/dev/null | sed -e "s#^$dir/##"
 390                ;;
 391        esac
 392}
 393
 394# __git_refs2 requires 1 argument (to pass to __git_refs)
 395__git_refs2 ()
 396{
 397        local i
 398        for i in $(__git_refs "$1"); do
 399                echo "$i:$i"
 400        done
 401}
 402
 403# __git_refs_remotes requires 1 argument (to pass to ls-remote)
 404__git_refs_remotes ()
 405{
 406        local i hash
 407        git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
 408        while read -r hash i; do
 409                echo "$i:refs/remotes/$1/${i#refs/heads/}"
 410        done
 411}
 412
 413__git_remotes ()
 414{
 415        local d="$(__gitdir)"
 416        test -d "$d/remotes" && ls -1 "$d/remotes"
 417        git --git-dir="$d" remote
 418}
 419
 420__git_list_merge_strategies ()
 421{
 422        git merge -s help 2>&1 |
 423        sed -n -e '/[Aa]vailable strategies are: /,/^$/{
 424                s/\.$//
 425                s/.*://
 426                s/^[    ]*//
 427                s/[     ]*$//
 428                p
 429        }'
 430}
 431
 432__git_merge_strategies=
 433# 'git merge -s help' (and thus detection of the merge strategy
 434# list) fails, unfortunately, if run outside of any git working
 435# tree.  __git_merge_strategies is set to the empty string in
 436# that case, and the detection will be repeated the next time it
 437# is needed.
 438__git_compute_merge_strategies ()
 439{
 440        test -n "$__git_merge_strategies" ||
 441        __git_merge_strategies=$(__git_list_merge_strategies)
 442}
 443
 444__git_complete_revlist_file ()
 445{
 446        local pfx ls ref cur_="$cur"
 447        case "$cur_" in
 448        *..?*:*)
 449                return
 450                ;;
 451        ?*:*)
 452                ref="${cur_%%:*}"
 453                cur_="${cur_#*:}"
 454                case "$cur_" in
 455                ?*/*)
 456                        pfx="${cur_%/*}"
 457                        cur_="${cur_##*/}"
 458                        ls="$ref:$pfx"
 459                        pfx="$pfx/"
 460                        ;;
 461                *)
 462                        ls="$ref"
 463                        ;;
 464                esac
 465
 466                case "$COMP_WORDBREAKS" in
 467                *:*) : great ;;
 468                *)   pfx="$ref:$pfx" ;;
 469                esac
 470
 471                __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \
 472                                | sed '/^100... blob /{
 473                                           s,^.*        ,,
 474                                           s,$, ,
 475                                       }
 476                                       /^120000 blob /{
 477                                           s,^.*        ,,
 478                                           s,$, ,
 479                                       }
 480                                       /^040000 tree /{
 481                                           s,^.*        ,,
 482                                           s,$,/,
 483                                       }
 484                                       s/^.*    //')" \
 485                        "$pfx" "$cur_" ""
 486                ;;
 487        *...*)
 488                pfx="${cur_%...*}..."
 489                cur_="${cur_#*...}"
 490                __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 491                ;;
 492        *..*)
 493                pfx="${cur_%..*}.."
 494                cur_="${cur_#*..}"
 495                __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 496                ;;
 497        *)
 498                __gitcomp_nl "$(__git_refs)"
 499                ;;
 500        esac
 501}
 502
 503
 504# __git_complete_index_file requires 1 argument:
 505# 1: the options to pass to ls-file
 506#
 507# The exception is --committable, which finds the files appropriate commit.
 508__git_complete_index_file ()
 509{
 510        local pfx="" cur_="$cur"
 511
 512        case "$cur_" in
 513        ?*/*)
 514                pfx="${cur_%/*}"
 515                cur_="${cur_##*/}"
 516                pfx="${pfx}/"
 517                ;;
 518        esac
 519
 520        __gitcomp_file "$(__git_index_files "$1" ${pfx:+"$pfx"})" "$pfx" "$cur_"
 521}
 522
 523__git_complete_file ()
 524{
 525        __git_complete_revlist_file
 526}
 527
 528__git_complete_revlist ()
 529{
 530        __git_complete_revlist_file
 531}
 532
 533__git_complete_remote_or_refspec ()
 534{
 535        local cur_="$cur" cmd="${words[1]}"
 536        local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
 537        if [ "$cmd" = "remote" ]; then
 538                ((c++))
 539        fi
 540        while [ $c -lt $cword ]; do
 541                i="${words[c]}"
 542                case "$i" in
 543                --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
 544                --all)
 545                        case "$cmd" in
 546                        push) no_complete_refspec=1 ;;
 547                        fetch)
 548                                return
 549                                ;;
 550                        *) ;;
 551                        esac
 552                        ;;
 553                -*) ;;
 554                *) remote="$i"; break ;;
 555                esac
 556                ((c++))
 557        done
 558        if [ -z "$remote" ]; then
 559                __gitcomp_nl "$(__git_remotes)"
 560                return
 561        fi
 562        if [ $no_complete_refspec = 1 ]; then
 563                return
 564        fi
 565        [ "$remote" = "." ] && remote=
 566        case "$cur_" in
 567        *:*)
 568                case "$COMP_WORDBREAKS" in
 569                *:*) : great ;;
 570                *)   pfx="${cur_%%:*}:" ;;
 571                esac
 572                cur_="${cur_#*:}"
 573                lhs=0
 574                ;;
 575        +*)
 576                pfx="+"
 577                cur_="${cur_#+}"
 578                ;;
 579        esac
 580        case "$cmd" in
 581        fetch)
 582                if [ $lhs = 1 ]; then
 583                        __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
 584                else
 585                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 586                fi
 587                ;;
 588        pull|remote)
 589                if [ $lhs = 1 ]; then
 590                        __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
 591                else
 592                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 593                fi
 594                ;;
 595        push)
 596                if [ $lhs = 1 ]; then
 597                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 598                else
 599                        __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
 600                fi
 601                ;;
 602        esac
 603}
 604
 605__git_complete_strategy ()
 606{
 607        __git_compute_merge_strategies
 608        case "$prev" in
 609        -s|--strategy)
 610                __gitcomp "$__git_merge_strategies"
 611                return 0
 612        esac
 613        case "$cur" in
 614        --strategy=*)
 615                __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
 616                return 0
 617                ;;
 618        esac
 619        return 1
 620}
 621
 622__git_commands () {
 623        if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}"
 624        then
 625                printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}"
 626        else
 627                git help -a|egrep '^  [a-zA-Z0-9]'
 628        fi
 629}
 630
 631__git_list_all_commands ()
 632{
 633        local i IFS=" "$'\n'
 634        for i in $(__git_commands)
 635        do
 636                case $i in
 637                *--*)             : helper pattern;;
 638                *) echo $i;;
 639                esac
 640        done
 641}
 642
 643__git_all_commands=
 644__git_compute_all_commands ()
 645{
 646        test -n "$__git_all_commands" ||
 647        __git_all_commands=$(__git_list_all_commands)
 648}
 649
 650__git_list_porcelain_commands ()
 651{
 652        local i IFS=" "$'\n'
 653        __git_compute_all_commands
 654        for i in $__git_all_commands
 655        do
 656                case $i in
 657                *--*)             : helper pattern;;
 658                applymbox)        : ask gittus;;
 659                applypatch)       : ask gittus;;
 660                archimport)       : import;;
 661                cat-file)         : plumbing;;
 662                check-attr)       : plumbing;;
 663                check-ignore)     : plumbing;;
 664                check-mailmap)    : plumbing;;
 665                check-ref-format) : plumbing;;
 666                checkout-index)   : plumbing;;
 667                column)           : internal helper;;
 668                commit-tree)      : plumbing;;
 669                count-objects)    : infrequent;;
 670                credential)       : credentials;;
 671                credential-*)     : credentials helper;;
 672                cvsexportcommit)  : export;;
 673                cvsimport)        : import;;
 674                cvsserver)        : daemon;;
 675                daemon)           : daemon;;
 676                diff-files)       : plumbing;;
 677                diff-index)       : plumbing;;
 678                diff-tree)        : plumbing;;
 679                fast-import)      : import;;
 680                fast-export)      : export;;
 681                fsck-objects)     : plumbing;;
 682                fetch-pack)       : plumbing;;
 683                fmt-merge-msg)    : plumbing;;
 684                for-each-ref)     : plumbing;;
 685                hash-object)      : plumbing;;
 686                http-*)           : transport;;
 687                index-pack)       : plumbing;;
 688                init-db)          : deprecated;;
 689                local-fetch)      : plumbing;;
 690                ls-files)         : plumbing;;
 691                ls-remote)        : plumbing;;
 692                ls-tree)          : plumbing;;
 693                mailinfo)         : plumbing;;
 694                mailsplit)        : plumbing;;
 695                merge-*)          : plumbing;;
 696                mktree)           : plumbing;;
 697                mktag)            : plumbing;;
 698                pack-objects)     : plumbing;;
 699                pack-redundant)   : plumbing;;
 700                pack-refs)        : plumbing;;
 701                parse-remote)     : plumbing;;
 702                patch-id)         : plumbing;;
 703                prune)            : plumbing;;
 704                prune-packed)     : plumbing;;
 705                quiltimport)      : import;;
 706                read-tree)        : plumbing;;
 707                receive-pack)     : plumbing;;
 708                remote-*)         : transport;;
 709                rerere)           : plumbing;;
 710                rev-list)         : plumbing;;
 711                rev-parse)        : plumbing;;
 712                runstatus)        : plumbing;;
 713                sh-setup)         : internal;;
 714                shell)            : daemon;;
 715                show-ref)         : plumbing;;
 716                send-pack)        : plumbing;;
 717                show-index)       : plumbing;;
 718                ssh-*)            : transport;;
 719                stripspace)       : plumbing;;
 720                symbolic-ref)     : plumbing;;
 721                unpack-file)      : plumbing;;
 722                unpack-objects)   : plumbing;;
 723                update-index)     : plumbing;;
 724                update-ref)       : plumbing;;
 725                update-server-info) : daemon;;
 726                upload-archive)   : plumbing;;
 727                upload-pack)      : plumbing;;
 728                write-tree)       : plumbing;;
 729                var)              : infrequent;;
 730                verify-pack)      : infrequent;;
 731                verify-tag)       : plumbing;;
 732                *) echo $i;;
 733                esac
 734        done
 735}
 736
 737__git_porcelain_commands=
 738__git_compute_porcelain_commands ()
 739{
 740        test -n "$__git_porcelain_commands" ||
 741        __git_porcelain_commands=$(__git_list_porcelain_commands)
 742}
 743
 744# Lists all set config variables starting with the given section prefix,
 745# with the prefix removed.
 746__git_get_config_variables ()
 747{
 748        local section="$1" i IFS=$'\n'
 749        for i in $(git --git-dir="$(__gitdir)" config --name-only --get-regexp "^$section\..*" 2>/dev/null); do
 750                echo "${i#$section.}"
 751        done
 752}
 753
 754__git_pretty_aliases ()
 755{
 756        __git_get_config_variables "pretty"
 757}
 758
 759__git_aliases ()
 760{
 761        __git_get_config_variables "alias"
 762}
 763
 764# __git_aliased_command requires 1 argument
 765__git_aliased_command ()
 766{
 767        local word cmdline=$(git --git-dir="$(__gitdir)" \
 768                config --get "alias.$1")
 769        for word in $cmdline; do
 770                case "$word" in
 771                \!gitk|gitk)
 772                        echo "gitk"
 773                        return
 774                        ;;
 775                \!*)    : shell command alias ;;
 776                -*)     : option ;;
 777                *=*)    : setting env ;;
 778                git)    : git itself ;;
 779                \(\))   : skip parens of shell function definition ;;
 780                {)      : skip start of shell helper function ;;
 781                :)      : skip null command ;;
 782                \'*)    : skip opening quote after sh -c ;;
 783                *)
 784                        echo "$word"
 785                        return
 786                esac
 787        done
 788}
 789
 790# __git_find_on_cmdline requires 1 argument
 791__git_find_on_cmdline ()
 792{
 793        local word subcommand c=1
 794        while [ $c -lt $cword ]; do
 795                word="${words[c]}"
 796                for subcommand in $1; do
 797                        if [ "$subcommand" = "$word" ]; then
 798                                echo "$subcommand"
 799                                return
 800                        fi
 801                done
 802                ((c++))
 803        done
 804}
 805
 806# Echo the value of an option set on the command line or config
 807#
 808# $1: short option name
 809# $2: long option name including =
 810# $3: list of possible values
 811# $4: config string (optional)
 812#
 813# example:
 814# result="$(__git_get_option_value "-d" "--do-something=" \
 815#     "yes no" "core.doSomething")"
 816#
 817# result is then either empty (no option set) or "yes" or "no"
 818#
 819# __git_get_option_value requires 3 arguments
 820__git_get_option_value ()
 821{
 822        local c short_opt long_opt val
 823        local result= values config_key word
 824
 825        short_opt="$1"
 826        long_opt="$2"
 827        values="$3"
 828        config_key="$4"
 829
 830        ((c = $cword - 1))
 831        while [ $c -ge 0 ]; do
 832                word="${words[c]}"
 833                for val in $values; do
 834                        if [ "$short_opt$val" = "$word" ] ||
 835                           [ "$long_opt$val"  = "$word" ]; then
 836                                result="$val"
 837                                break 2
 838                        fi
 839                done
 840                ((c--))
 841        done
 842
 843        if [ -n "$config_key" ] && [ -z "$result" ]; then
 844                result="$(git --git-dir="$(__gitdir)" config "$config_key")"
 845        fi
 846
 847        echo "$result"
 848}
 849
 850__git_has_doubledash ()
 851{
 852        local c=1
 853        while [ $c -lt $cword ]; do
 854                if [ "--" = "${words[c]}" ]; then
 855                        return 0
 856                fi
 857                ((c++))
 858        done
 859        return 1
 860}
 861
 862# Try to count non option arguments passed on the command line for the
 863# specified git command.
 864# When options are used, it is necessary to use the special -- option to
 865# tell the implementation were non option arguments begin.
 866# XXX this can not be improved, since options can appear everywhere, as
 867# an example:
 868#       git mv x -n y
 869#
 870# __git_count_arguments requires 1 argument: the git command executed.
 871__git_count_arguments ()
 872{
 873        local word i c=0
 874
 875        # Skip "git" (first argument)
 876        for ((i=1; i < ${#words[@]}; i++)); do
 877                word="${words[i]}"
 878
 879                case "$word" in
 880                        --)
 881                                # Good; we can assume that the following are only non
 882                                # option arguments.
 883                                ((c = 0))
 884                                ;;
 885                        "$1")
 886                                # Skip the specified git command and discard git
 887                                # main options
 888                                ((c = 0))
 889                                ;;
 890                        ?*)
 891                                ((c++))
 892                                ;;
 893                esac
 894        done
 895
 896        printf "%d" $c
 897}
 898
 899__git_whitespacelist="nowarn warn error error-all fix"
 900
 901_git_am ()
 902{
 903        local dir="$(__gitdir)"
 904        if [ -d "$dir"/rebase-apply ]; then
 905                __gitcomp "--skip --continue --resolved --abort"
 906                return
 907        fi
 908        case "$cur" in
 909        --whitespace=*)
 910                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 911                return
 912                ;;
 913        --*)
 914                __gitcomp "
 915                        --3way --committer-date-is-author-date --ignore-date
 916                        --ignore-whitespace --ignore-space-change
 917                        --interactive --keep --no-utf8 --signoff --utf8
 918                        --whitespace= --scissors
 919                        "
 920                return
 921        esac
 922}
 923
 924_git_apply ()
 925{
 926        case "$cur" in
 927        --whitespace=*)
 928                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 929                return
 930                ;;
 931        --*)
 932                __gitcomp "
 933                        --stat --numstat --summary --check --index
 934                        --cached --index-info --reverse --reject --unidiff-zero
 935                        --apply --no-add --exclude=
 936                        --ignore-whitespace --ignore-space-change
 937                        --whitespace= --inaccurate-eof --verbose
 938                        "
 939                return
 940        esac
 941}
 942
 943_git_add ()
 944{
 945        case "$cur" in
 946        --*)
 947                __gitcomp "
 948                        --interactive --refresh --patch --update --dry-run
 949                        --ignore-errors --intent-to-add
 950                        "
 951                return
 952        esac
 953
 954        # XXX should we check for --update and --all options ?
 955        __git_complete_index_file "--others --modified --directory --no-empty-directory"
 956}
 957
 958_git_archive ()
 959{
 960        case "$cur" in
 961        --format=*)
 962                __gitcomp "$(git archive --list)" "" "${cur##--format=}"
 963                return
 964                ;;
 965        --remote=*)
 966                __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
 967                return
 968                ;;
 969        --*)
 970                __gitcomp "
 971                        --format= --list --verbose
 972                        --prefix= --remote= --exec=
 973                        "
 974                return
 975                ;;
 976        esac
 977        __git_complete_file
 978}
 979
 980_git_bisect ()
 981{
 982        __git_has_doubledash && return
 983
 984        local subcommands="start bad good skip reset visualize replay log run"
 985        local subcommand="$(__git_find_on_cmdline "$subcommands")"
 986        if [ -z "$subcommand" ]; then
 987                if [ -f "$(__gitdir)"/BISECT_START ]; then
 988                        __gitcomp "$subcommands"
 989                else
 990                        __gitcomp "replay start"
 991                fi
 992                return
 993        fi
 994
 995        case "$subcommand" in
 996        bad|good|reset|skip|start)
 997                __gitcomp_nl "$(__git_refs)"
 998                ;;
 999        *)
1000                ;;
1001        esac
1002}
1003
1004_git_branch ()
1005{
1006        local i c=1 only_local_ref="n" has_r="n"
1007
1008        while [ $c -lt $cword ]; do
1009                i="${words[c]}"
1010                case "$i" in
1011                -d|-m)  only_local_ref="y" ;;
1012                -r)     has_r="y" ;;
1013                esac
1014                ((c++))
1015        done
1016
1017        case "$cur" in
1018        --set-upstream-to=*)
1019                __gitcomp_nl "$(__git_refs)" "" "${cur##--set-upstream-to=}"
1020                ;;
1021        --*)
1022                __gitcomp "
1023                        --color --no-color --verbose --abbrev= --no-abbrev
1024                        --track --no-track --contains --merged --no-merged
1025                        --set-upstream-to= --edit-description --list
1026                        --unset-upstream
1027                        "
1028                ;;
1029        *)
1030                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
1031                        __gitcomp_nl "$(__git_heads)"
1032                else
1033                        __gitcomp_nl "$(__git_refs)"
1034                fi
1035                ;;
1036        esac
1037}
1038
1039_git_bundle ()
1040{
1041        local cmd="${words[2]}"
1042        case "$cword" in
1043        2)
1044                __gitcomp "create list-heads verify unbundle"
1045                ;;
1046        3)
1047                # looking for a file
1048                ;;
1049        *)
1050                case "$cmd" in
1051                        create)
1052                                __git_complete_revlist
1053                        ;;
1054                esac
1055                ;;
1056        esac
1057}
1058
1059_git_checkout ()
1060{
1061        __git_has_doubledash && return
1062
1063        case "$cur" in
1064        --conflict=*)
1065                __gitcomp "diff3 merge" "" "${cur##--conflict=}"
1066                ;;
1067        --*)
1068                __gitcomp "
1069                        --quiet --ours --theirs --track --no-track --merge
1070                        --conflict= --orphan --patch
1071                        "
1072                ;;
1073        *)
1074                # check if --track, --no-track, or --no-guess was specified
1075                # if so, disable DWIM mode
1076                local flags="--track --no-track --no-guess" track=1
1077                if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
1078                        track=''
1079                fi
1080                __gitcomp_nl "$(__git_refs '' $track)"
1081                ;;
1082        esac
1083}
1084
1085_git_cherry ()
1086{
1087        __gitcomp_nl "$(__git_refs)"
1088}
1089
1090_git_cherry_pick ()
1091{
1092        local dir="$(__gitdir)"
1093        if [ -f "$dir"/CHERRY_PICK_HEAD ]; then
1094                __gitcomp "--continue --quit --abort"
1095                return
1096        fi
1097        case "$cur" in
1098        --*)
1099                __gitcomp "--edit --no-commit --signoff --strategy= --mainline"
1100                ;;
1101        *)
1102                __gitcomp_nl "$(__git_refs)"
1103                ;;
1104        esac
1105}
1106
1107_git_clean ()
1108{
1109        case "$cur" in
1110        --*)
1111                __gitcomp "--dry-run --quiet"
1112                return
1113                ;;
1114        esac
1115
1116        # XXX should we check for -x option ?
1117        __git_complete_index_file "--others --directory"
1118}
1119
1120_git_clone ()
1121{
1122        case "$cur" in
1123        --*)
1124                __gitcomp "
1125                        --local
1126                        --no-hardlinks
1127                        --shared
1128                        --reference
1129                        --quiet
1130                        --no-checkout
1131                        --bare
1132                        --mirror
1133                        --origin
1134                        --upload-pack
1135                        --template=
1136                        --depth
1137                        --single-branch
1138                        --branch
1139                        "
1140                return
1141                ;;
1142        esac
1143}
1144
1145__git_untracked_file_modes="all no normal"
1146
1147_git_commit ()
1148{
1149        case "$prev" in
1150        -c|-C)
1151                __gitcomp_nl "$(__git_refs)" "" "${cur}"
1152                return
1153                ;;
1154        esac
1155
1156        case "$cur" in
1157        --cleanup=*)
1158                __gitcomp "default scissors strip verbatim whitespace
1159                        " "" "${cur##--cleanup=}"
1160                return
1161                ;;
1162        --reuse-message=*|--reedit-message=*|\
1163        --fixup=*|--squash=*)
1164                __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1165                return
1166                ;;
1167        --untracked-files=*)
1168                __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
1169                return
1170                ;;
1171        --*)
1172                __gitcomp "
1173                        --all --author= --signoff --verify --no-verify
1174                        --edit --no-edit
1175                        --amend --include --only --interactive
1176                        --dry-run --reuse-message= --reedit-message=
1177                        --reset-author --file= --message= --template=
1178                        --cleanup= --untracked-files --untracked-files=
1179                        --verbose --quiet --fixup= --squash=
1180                        "
1181                return
1182        esac
1183
1184        if git rev-parse --verify --quiet HEAD >/dev/null; then
1185                __git_complete_index_file "--committable"
1186        else
1187                # This is the first commit
1188                __git_complete_index_file "--cached"
1189        fi
1190}
1191
1192_git_describe ()
1193{
1194        case "$cur" in
1195        --*)
1196                __gitcomp "
1197                        --all --tags --contains --abbrev= --candidates=
1198                        --exact-match --debug --long --match --always
1199                        "
1200                return
1201        esac
1202        __gitcomp_nl "$(__git_refs)"
1203}
1204
1205__git_diff_algorithms="myers minimal patience histogram"
1206
1207__git_diff_common_options="--stat --numstat --shortstat --summary
1208                        --patch-with-stat --name-only --name-status --color
1209                        --no-color --color-words --no-renames --check
1210                        --full-index --binary --abbrev --diff-filter=
1211                        --find-copies-harder
1212                        --text --ignore-space-at-eol --ignore-space-change
1213                        --ignore-all-space --ignore-blank-lines --exit-code
1214                        --quiet --ext-diff --no-ext-diff
1215                        --no-prefix --src-prefix= --dst-prefix=
1216                        --inter-hunk-context=
1217                        --patience --histogram --minimal
1218                        --raw --word-diff --word-diff-regex=
1219                        --dirstat --dirstat= --dirstat-by-file
1220                        --dirstat-by-file= --cumulative
1221                        --diff-algorithm=
1222"
1223
1224_git_diff ()
1225{
1226        __git_has_doubledash && return
1227
1228        case "$cur" in
1229        --diff-algorithm=*)
1230                __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
1231                return
1232                ;;
1233        --*)
1234                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1235                        --base --ours --theirs --no-index
1236                        $__git_diff_common_options
1237                        "
1238                return
1239                ;;
1240        esac
1241        __git_complete_revlist_file
1242}
1243
1244__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
1245                        tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc codecompare
1246"
1247
1248_git_difftool ()
1249{
1250        __git_has_doubledash && return
1251
1252        case "$cur" in
1253        --tool=*)
1254                __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
1255                return
1256                ;;
1257        --*)
1258                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1259                        --base --ours --theirs
1260                        --no-renames --diff-filter= --find-copies-harder
1261                        --relative --ignore-submodules
1262                        --tool="
1263                return
1264                ;;
1265        esac
1266        __git_complete_revlist_file
1267}
1268
1269__git_fetch_recurse_submodules="yes on-demand no"
1270
1271__git_fetch_options="
1272        --quiet --verbose --append --upload-pack --force --keep --depth=
1273        --tags --no-tags --all --prune --dry-run --recurse-submodules=
1274"
1275
1276_git_fetch ()
1277{
1278        case "$cur" in
1279        --recurse-submodules=*)
1280                __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
1281                return
1282                ;;
1283        --*)
1284                __gitcomp "$__git_fetch_options"
1285                return
1286                ;;
1287        esac
1288        __git_complete_remote_or_refspec
1289}
1290
1291__git_format_patch_options="
1292        --stdout --attach --no-attach --thread --thread= --no-thread
1293        --numbered --start-number --numbered-files --keep-subject --signoff
1294        --signature --no-signature --in-reply-to= --cc= --full-index --binary
1295        --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix=
1296        --inline --suffix= --ignore-if-in-upstream --subject-prefix=
1297        --output-directory --reroll-count --to= --quiet --notes
1298"
1299
1300_git_format_patch ()
1301{
1302        case "$cur" in
1303        --thread=*)
1304                __gitcomp "
1305                        deep shallow
1306                        " "" "${cur##--thread=}"
1307                return
1308                ;;
1309        --*)
1310                __gitcomp "$__git_format_patch_options"
1311                return
1312                ;;
1313        esac
1314        __git_complete_revlist
1315}
1316
1317_git_fsck ()
1318{
1319        case "$cur" in
1320        --*)
1321                __gitcomp "
1322                        --tags --root --unreachable --cache --no-reflogs --full
1323                        --strict --verbose --lost-found
1324                        "
1325                return
1326                ;;
1327        esac
1328}
1329
1330_git_gc ()
1331{
1332        case "$cur" in
1333        --*)
1334                __gitcomp "--prune --aggressive"
1335                return
1336                ;;
1337        esac
1338}
1339
1340_git_gitk ()
1341{
1342        _gitk
1343}
1344
1345__git_match_ctag() {
1346        awk "/^${1//\//\\/}/ { print \$1 }" "$2"
1347}
1348
1349_git_grep ()
1350{
1351        __git_has_doubledash && return
1352
1353        case "$cur" in
1354        --*)
1355                __gitcomp "
1356                        --cached
1357                        --text --ignore-case --word-regexp --invert-match
1358                        --full-name --line-number
1359                        --extended-regexp --basic-regexp --fixed-strings
1360                        --perl-regexp
1361                        --threads
1362                        --files-with-matches --name-only
1363                        --files-without-match
1364                        --max-depth
1365                        --count
1366                        --and --or --not --all-match
1367                        "
1368                return
1369                ;;
1370        esac
1371
1372        case "$cword,$prev" in
1373        2,*|*,-*)
1374                if test -r tags; then
1375                        __gitcomp_nl "$(__git_match_ctag "$cur" tags)"
1376                        return
1377                fi
1378                ;;
1379        esac
1380
1381        __gitcomp_nl "$(__git_refs)"
1382}
1383
1384_git_help ()
1385{
1386        case "$cur" in
1387        --*)
1388                __gitcomp "--all --guides --info --man --web"
1389                return
1390                ;;
1391        esac
1392        __git_compute_all_commands
1393        __gitcomp "$__git_all_commands $(__git_aliases)
1394                attributes cli core-tutorial cvs-migration
1395                diffcore everyday gitk glossary hooks ignore modules
1396                namespaces repository-layout revisions tutorial tutorial-2
1397                workflows
1398                "
1399}
1400
1401_git_init ()
1402{
1403        case "$cur" in
1404        --shared=*)
1405                __gitcomp "
1406                        false true umask group all world everybody
1407                        " "" "${cur##--shared=}"
1408                return
1409                ;;
1410        --*)
1411                __gitcomp "--quiet --bare --template= --shared --shared="
1412                return
1413                ;;
1414        esac
1415}
1416
1417_git_ls_files ()
1418{
1419        case "$cur" in
1420        --*)
1421                __gitcomp "--cached --deleted --modified --others --ignored
1422                        --stage --directory --no-empty-directory --unmerged
1423                        --killed --exclude= --exclude-from=
1424                        --exclude-per-directory= --exclude-standard
1425                        --error-unmatch --with-tree= --full-name
1426                        --abbrev --ignored --exclude-per-directory
1427                        "
1428                return
1429                ;;
1430        esac
1431
1432        # XXX ignore options like --modified and always suggest all cached
1433        # files.
1434        __git_complete_index_file "--cached"
1435}
1436
1437_git_ls_remote ()
1438{
1439        __gitcomp_nl "$(__git_remotes)"
1440}
1441
1442_git_ls_tree ()
1443{
1444        __git_complete_file
1445}
1446
1447# Options that go well for log, shortlog and gitk
1448__git_log_common_options="
1449        --not --all
1450        --branches --tags --remotes
1451        --first-parent --merges --no-merges
1452        --max-count=
1453        --max-age= --since= --after=
1454        --min-age= --until= --before=
1455        --min-parents= --max-parents=
1456        --no-min-parents --no-max-parents
1457"
1458# Options that go well for log and gitk (not shortlog)
1459__git_log_gitk_options="
1460        --dense --sparse --full-history
1461        --simplify-merges --simplify-by-decoration
1462        --left-right --notes --no-notes
1463"
1464# Options that go well for log and shortlog (not gitk)
1465__git_log_shortlog_options="
1466        --author= --committer= --grep=
1467        --all-match --invert-grep
1468"
1469
1470__git_log_pretty_formats="oneline short medium full fuller email raw format:"
1471__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1472
1473_git_log ()
1474{
1475        __git_has_doubledash && return
1476
1477        local g="$(git rev-parse --git-dir 2>/dev/null)"
1478        local merge=""
1479        if [ -f "$g/MERGE_HEAD" ]; then
1480                merge="--merge"
1481        fi
1482        case "$cur" in
1483        --pretty=*|--format=*)
1484                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
1485                        " "" "${cur#*=}"
1486                return
1487                ;;
1488        --date=*)
1489                __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1490                return
1491                ;;
1492        --decorate=*)
1493                __gitcomp "full short no" "" "${cur##--decorate=}"
1494                return
1495                ;;
1496        --*)
1497                __gitcomp "
1498                        $__git_log_common_options
1499                        $__git_log_shortlog_options
1500                        $__git_log_gitk_options
1501                        --root --topo-order --date-order --reverse
1502                        --follow --full-diff
1503                        --abbrev-commit --abbrev=
1504                        --relative-date --date=
1505                        --pretty= --format= --oneline
1506                        --show-signature
1507                        --cherry-mark
1508                        --cherry-pick
1509                        --graph
1510                        --decorate --decorate=
1511                        --walk-reflogs
1512                        --parents --children
1513                        $merge
1514                        $__git_diff_common_options
1515                        --pickaxe-all --pickaxe-regex
1516                        "
1517                return
1518                ;;
1519        esac
1520        __git_complete_revlist
1521}
1522
1523# Common merge options shared by git-merge(1) and git-pull(1).
1524__git_merge_options="
1525        --no-commit --no-stat --log --no-log --squash --strategy
1526        --commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit
1527        --verify-signatures --no-verify-signatures --gpg-sign
1528        --quiet --verbose --progress --no-progress
1529"
1530
1531_git_merge ()
1532{
1533        __git_complete_strategy && return
1534
1535        case "$cur" in
1536        --*)
1537                __gitcomp "$__git_merge_options
1538                        --rerere-autoupdate --no-rerere-autoupdate --abort"
1539                return
1540        esac
1541        __gitcomp_nl "$(__git_refs)"
1542}
1543
1544_git_mergetool ()
1545{
1546        case "$cur" in
1547        --tool=*)
1548                __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1549                return
1550                ;;
1551        --*)
1552                __gitcomp "--tool="
1553                return
1554                ;;
1555        esac
1556}
1557
1558_git_merge_base ()
1559{
1560        case "$cur" in
1561        --*)
1562                __gitcomp "--octopus --independent --is-ancestor --fork-point"
1563                return
1564                ;;
1565        esac
1566        __gitcomp_nl "$(__git_refs)"
1567}
1568
1569_git_mv ()
1570{
1571        case "$cur" in
1572        --*)
1573                __gitcomp "--dry-run"
1574                return
1575                ;;
1576        esac
1577
1578        if [ $(__git_count_arguments "mv") -gt 0 ]; then
1579                # We need to show both cached and untracked files (including
1580                # empty directories) since this may not be the last argument.
1581                __git_complete_index_file "--cached --others --directory"
1582        else
1583                __git_complete_index_file "--cached"
1584        fi
1585}
1586
1587_git_name_rev ()
1588{
1589        __gitcomp "--tags --all --stdin"
1590}
1591
1592_git_notes ()
1593{
1594        local subcommands='add append copy edit list prune remove show'
1595        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1596
1597        case "$subcommand,$cur" in
1598        ,--*)
1599                __gitcomp '--ref'
1600                ;;
1601        ,*)
1602                case "$prev" in
1603                --ref)
1604                        __gitcomp_nl "$(__git_refs)"
1605                        ;;
1606                *)
1607                        __gitcomp "$subcommands --ref"
1608                        ;;
1609                esac
1610                ;;
1611        add,--reuse-message=*|append,--reuse-message=*|\
1612        add,--reedit-message=*|append,--reedit-message=*)
1613                __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1614                ;;
1615        add,--*|append,--*)
1616                __gitcomp '--file= --message= --reedit-message=
1617                                --reuse-message='
1618                ;;
1619        copy,--*)
1620                __gitcomp '--stdin'
1621                ;;
1622        prune,--*)
1623                __gitcomp '--dry-run --verbose'
1624                ;;
1625        prune,*)
1626                ;;
1627        *)
1628                case "$prev" in
1629                -m|-F)
1630                        ;;
1631                *)
1632                        __gitcomp_nl "$(__git_refs)"
1633                        ;;
1634                esac
1635                ;;
1636        esac
1637}
1638
1639_git_pull ()
1640{
1641        __git_complete_strategy && return
1642
1643        case "$cur" in
1644        --recurse-submodules=*)
1645                __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
1646                return
1647                ;;
1648        --*)
1649                __gitcomp "
1650                        --rebase --no-rebase
1651                        $__git_merge_options
1652                        $__git_fetch_options
1653                "
1654                return
1655                ;;
1656        esac
1657        __git_complete_remote_or_refspec
1658}
1659
1660__git_push_recurse_submodules="check on-demand"
1661
1662__git_complete_force_with_lease ()
1663{
1664        local cur_=$1
1665
1666        case "$cur_" in
1667        --*=)
1668                ;;
1669        *:*)
1670                __gitcomp_nl "$(__git_refs)" "" "${cur_#*:}"
1671                ;;
1672        *)
1673                __gitcomp_nl "$(__git_refs)" "" "$cur_"
1674                ;;
1675        esac
1676}
1677
1678_git_push ()
1679{
1680        case "$prev" in
1681        --repo)
1682                __gitcomp_nl "$(__git_remotes)"
1683                return
1684                ;;
1685        --recurse-submodules)
1686                __gitcomp "$__git_push_recurse_submodules"
1687                return
1688                ;;
1689        esac
1690        case "$cur" in
1691        --repo=*)
1692                __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
1693                return
1694                ;;
1695        --recurse-submodules=*)
1696                __gitcomp "$__git_push_recurse_submodules" "" "${cur##--recurse-submodules=}"
1697                return
1698                ;;
1699        --force-with-lease=*)
1700                __git_complete_force_with_lease "${cur##--force-with-lease=}"
1701                return
1702                ;;
1703        --*)
1704                __gitcomp "
1705                        --all --mirror --tags --dry-run --force --verbose
1706                        --quiet --prune --delete --follow-tags
1707                        --receive-pack= --repo= --set-upstream
1708                        --force-with-lease --force-with-lease= --recurse-submodules=
1709                "
1710                return
1711                ;;
1712        esac
1713        __git_complete_remote_or_refspec
1714}
1715
1716_git_rebase ()
1717{
1718        local dir="$(__gitdir)"
1719        if [ -f "$dir"/rebase-merge/interactive ]; then
1720                __gitcomp "--continue --skip --abort --edit-todo"
1721                return
1722        elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1723                __gitcomp "--continue --skip --abort"
1724                return
1725        fi
1726        __git_complete_strategy && return
1727        case "$cur" in
1728        --whitespace=*)
1729                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1730                return
1731                ;;
1732        --*)
1733                __gitcomp "
1734                        --onto --merge --strategy --interactive
1735                        --preserve-merges --stat --no-stat
1736                        --committer-date-is-author-date --ignore-date
1737                        --ignore-whitespace --whitespace=
1738                        --autosquash --no-autosquash
1739                        --fork-point --no-fork-point
1740                        --autostash --no-autostash
1741                        --verify --no-verify
1742                        --keep-empty --root --force-rebase --no-ff
1743                        --exec
1744                        "
1745
1746                return
1747        esac
1748        __gitcomp_nl "$(__git_refs)"
1749}
1750
1751_git_reflog ()
1752{
1753        local subcommands="show delete expire"
1754        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1755
1756        if [ -z "$subcommand" ]; then
1757                __gitcomp "$subcommands"
1758        else
1759                __gitcomp_nl "$(__git_refs)"
1760        fi
1761}
1762
1763__git_send_email_confirm_options="always never auto cc compose"
1764__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1765
1766_git_send_email ()
1767{
1768        case "$prev" in
1769        --to|--cc|--bcc|--from)
1770                __gitcomp "
1771                $(git --git-dir="$(__gitdir)" send-email --dump-aliases 2>/dev/null)
1772                "
1773                return
1774                ;;
1775        esac
1776
1777        case "$cur" in
1778        --confirm=*)
1779                __gitcomp "
1780                        $__git_send_email_confirm_options
1781                        " "" "${cur##--confirm=}"
1782                return
1783                ;;
1784        --suppress-cc=*)
1785                __gitcomp "
1786                        $__git_send_email_suppresscc_options
1787                        " "" "${cur##--suppress-cc=}"
1788
1789                return
1790                ;;
1791        --smtp-encryption=*)
1792                __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
1793                return
1794                ;;
1795        --thread=*)
1796                __gitcomp "
1797                        deep shallow
1798                        " "" "${cur##--thread=}"
1799                return
1800                ;;
1801        --to=*|--cc=*|--bcc=*|--from=*)
1802                __gitcomp "
1803                $(git --git-dir="$(__gitdir)" send-email --dump-aliases 2>/dev/null)
1804                " "" "${cur#--*=}"
1805                return
1806                ;;
1807        --*)
1808                __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1809                        --compose --confirm= --dry-run --envelope-sender
1810                        --from --identity
1811                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1812                        --no-suppress-from --no-thread --quiet
1813                        --signed-off-by-cc --smtp-pass --smtp-server
1814                        --smtp-server-port --smtp-encryption= --smtp-user
1815                        --subject --suppress-cc= --suppress-from --thread --to
1816                        --validate --no-validate
1817                        $__git_format_patch_options"
1818                return
1819                ;;
1820        esac
1821        __git_complete_revlist
1822}
1823
1824_git_stage ()
1825{
1826        _git_add
1827}
1828
1829_git_status ()
1830{
1831        local complete_opt
1832        local untracked_state
1833
1834        case "$cur" in
1835        --ignore-submodules=*)
1836                __gitcomp "none untracked dirty all" "" "${cur##--ignore-submodules=}"
1837                return
1838                ;;
1839        --untracked-files=*)
1840                __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
1841                return
1842                ;;
1843        --column=*)
1844                __gitcomp "
1845                        always never auto column row plain dense nodense
1846                        " "" "${cur##--column=}"
1847                return
1848                ;;
1849        --*)
1850                __gitcomp "
1851                        --short --branch --porcelain --long --verbose
1852                        --untracked-files= --ignore-submodules= --ignored
1853                        --column= --no-column
1854                        "
1855                return
1856                ;;
1857        esac
1858
1859        untracked_state="$(__git_get_option_value "-u" "--untracked-files=" \
1860                "$__git_untracked_file_modes" "status.showUntrackedFiles")"
1861
1862        case "$untracked_state" in
1863        no)
1864                # --ignored option does not matter
1865                complete_opt=
1866                ;;
1867        all|normal|*)
1868                complete_opt="--cached --directory --no-empty-directory --others"
1869
1870                if [ -n "$(__git_find_on_cmdline "--ignored")" ]; then
1871                        complete_opt="$complete_opt --ignored --exclude=*"
1872                fi
1873                ;;
1874        esac
1875
1876        __git_complete_index_file "$complete_opt"
1877}
1878
1879__git_config_get_set_variables ()
1880{
1881        local prevword word config_file= c=$cword
1882        while [ $c -gt 1 ]; do
1883                word="${words[c]}"
1884                case "$word" in
1885                --system|--global|--local|--file=*)
1886                        config_file="$word"
1887                        break
1888                        ;;
1889                -f|--file)
1890                        config_file="$word $prevword"
1891                        break
1892                        ;;
1893                esac
1894                prevword=$word
1895                c=$((--c))
1896        done
1897
1898        git --git-dir="$(__gitdir)" config $config_file --name-only --list 2>/dev/null
1899}
1900
1901_git_config ()
1902{
1903        case "$prev" in
1904        branch.*.remote|branch.*.pushremote)
1905                __gitcomp_nl "$(__git_remotes)"
1906                return
1907                ;;
1908        branch.*.merge)
1909                __gitcomp_nl "$(__git_refs)"
1910                return
1911                ;;
1912        branch.*.rebase)
1913                __gitcomp "false true preserve interactive"
1914                return
1915                ;;
1916        remote.pushdefault)
1917                __gitcomp_nl "$(__git_remotes)"
1918                return
1919                ;;
1920        remote.*.fetch)
1921                local remote="${prev#remote.}"
1922                remote="${remote%.fetch}"
1923                if [ -z "$cur" ]; then
1924                        __gitcomp_nl "refs/heads/" "" "" ""
1925                        return
1926                fi
1927                __gitcomp_nl "$(__git_refs_remotes "$remote")"
1928                return
1929                ;;
1930        remote.*.push)
1931                local remote="${prev#remote.}"
1932                remote="${remote%.push}"
1933                __gitcomp_nl "$(git --git-dir="$(__gitdir)" \
1934                        for-each-ref --format='%(refname):%(refname)' \
1935                        refs/heads)"
1936                return
1937                ;;
1938        pull.twohead|pull.octopus)
1939                __git_compute_merge_strategies
1940                __gitcomp "$__git_merge_strategies"
1941                return
1942                ;;
1943        color.branch|color.diff|color.interactive|\
1944        color.showbranch|color.status|color.ui)
1945                __gitcomp "always never auto"
1946                return
1947                ;;
1948        color.pager)
1949                __gitcomp "false true"
1950                return
1951                ;;
1952        color.*.*)
1953                __gitcomp "
1954                        normal black red green yellow blue magenta cyan white
1955                        bold dim ul blink reverse
1956                        "
1957                return
1958                ;;
1959        diff.submodule)
1960                __gitcomp "log short"
1961                return
1962                ;;
1963        help.format)
1964                __gitcomp "man info web html"
1965                return
1966                ;;
1967        log.date)
1968                __gitcomp "$__git_log_date_formats"
1969                return
1970                ;;
1971        sendemail.aliasesfiletype)
1972                __gitcomp "mutt mailrc pine elm gnus"
1973                return
1974                ;;
1975        sendemail.confirm)
1976                __gitcomp "$__git_send_email_confirm_options"
1977                return
1978                ;;
1979        sendemail.suppresscc)
1980                __gitcomp "$__git_send_email_suppresscc_options"
1981                return
1982                ;;
1983        sendemail.transferencoding)
1984                __gitcomp "7bit 8bit quoted-printable base64"
1985                return
1986                ;;
1987        --get|--get-all|--unset|--unset-all)
1988                __gitcomp_nl "$(__git_config_get_set_variables)"
1989                return
1990                ;;
1991        *.*)
1992                return
1993                ;;
1994        esac
1995        case "$cur" in
1996        --*)
1997                __gitcomp "
1998                        --system --global --local --file=
1999                        --list --replace-all
2000                        --get --get-all --get-regexp
2001                        --add --unset --unset-all
2002                        --remove-section --rename-section
2003                        --name-only
2004                        "
2005                return
2006                ;;
2007        branch.*.*)
2008                local pfx="${cur%.*}." cur_="${cur##*.}"
2009                __gitcomp "remote pushremote merge mergeoptions rebase" "$pfx" "$cur_"
2010                return
2011                ;;
2012        branch.*)
2013                local pfx="${cur%.*}." cur_="${cur#*.}"
2014                __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
2015                __gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_"
2016                return
2017                ;;
2018        guitool.*.*)
2019                local pfx="${cur%.*}." cur_="${cur##*.}"
2020                __gitcomp "
2021                        argprompt cmd confirm needsfile noconsole norescan
2022                        prompt revprompt revunmerged title
2023                        " "$pfx" "$cur_"
2024                return
2025                ;;
2026        difftool.*.*)
2027                local pfx="${cur%.*}." cur_="${cur##*.}"
2028                __gitcomp "cmd path" "$pfx" "$cur_"
2029                return
2030                ;;
2031        man.*.*)
2032                local pfx="${cur%.*}." cur_="${cur##*.}"
2033                __gitcomp "cmd path" "$pfx" "$cur_"
2034                return
2035                ;;
2036        mergetool.*.*)
2037                local pfx="${cur%.*}." cur_="${cur##*.}"
2038                __gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
2039                return
2040                ;;
2041        pager.*)
2042                local pfx="${cur%.*}." cur_="${cur#*.}"
2043                __git_compute_all_commands
2044                __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
2045                return
2046                ;;
2047        remote.*.*)
2048                local pfx="${cur%.*}." cur_="${cur##*.}"
2049                __gitcomp "
2050                        url proxy fetch push mirror skipDefaultUpdate
2051                        receivepack uploadpack tagopt pushurl
2052                        " "$pfx" "$cur_"
2053                return
2054                ;;
2055        remote.*)
2056                local pfx="${cur%.*}." cur_="${cur#*.}"
2057                __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
2058                __gitcomp_nl_append "pushdefault" "$pfx" "$cur_"
2059                return
2060                ;;
2061        url.*.*)
2062                local pfx="${cur%.*}." cur_="${cur##*.}"
2063                __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
2064                return
2065                ;;
2066        esac
2067        __gitcomp "
2068                add.ignoreErrors
2069                advice.commitBeforeMerge
2070                advice.detachedHead
2071                advice.implicitIdentity
2072                advice.pushNonFastForward
2073                advice.resolveConflict
2074                advice.statusHints
2075                alias.
2076                am.keepcr
2077                apply.ignorewhitespace
2078                apply.whitespace
2079                branch.autosetupmerge
2080                branch.autosetuprebase
2081                browser.
2082                clean.requireForce
2083                color.branch
2084                color.branch.current
2085                color.branch.local
2086                color.branch.plain
2087                color.branch.remote
2088                color.decorate.HEAD
2089                color.decorate.branch
2090                color.decorate.remoteBranch
2091                color.decorate.stash
2092                color.decorate.tag
2093                color.diff
2094                color.diff.commit
2095                color.diff.frag
2096                color.diff.func
2097                color.diff.meta
2098                color.diff.new
2099                color.diff.old
2100                color.diff.plain
2101                color.diff.whitespace
2102                color.grep
2103                color.grep.context
2104                color.grep.filename
2105                color.grep.function
2106                color.grep.linenumber
2107                color.grep.match
2108                color.grep.selected
2109                color.grep.separator
2110                color.interactive
2111                color.interactive.error
2112                color.interactive.header
2113                color.interactive.help
2114                color.interactive.prompt
2115                color.pager
2116                color.showbranch
2117                color.status
2118                color.status.added
2119                color.status.changed
2120                color.status.header
2121                color.status.nobranch
2122                color.status.unmerged
2123                color.status.untracked
2124                color.status.updated
2125                color.ui
2126                commit.status
2127                commit.template
2128                core.abbrev
2129                core.askpass
2130                core.attributesfile
2131                core.autocrlf
2132                core.bare
2133                core.bigFileThreshold
2134                core.compression
2135                core.createObject
2136                core.deltaBaseCacheLimit
2137                core.editor
2138                core.eol
2139                core.excludesfile
2140                core.fileMode
2141                core.fsyncobjectfiles
2142                core.gitProxy
2143                core.ignoreStat
2144                core.ignorecase
2145                core.logAllRefUpdates
2146                core.loosecompression
2147                core.notesRef
2148                core.packedGitLimit
2149                core.packedGitWindowSize
2150                core.pager
2151                core.preferSymlinkRefs
2152                core.preloadindex
2153                core.quotepath
2154                core.repositoryFormatVersion
2155                core.safecrlf
2156                core.sharedRepository
2157                core.sparseCheckout
2158                core.symlinks
2159                core.trustctime
2160                core.untrackedCache
2161                core.warnAmbiguousRefs
2162                core.whitespace
2163                core.worktree
2164                diff.autorefreshindex
2165                diff.external
2166                diff.ignoreSubmodules
2167                diff.mnemonicprefix
2168                diff.noprefix
2169                diff.renameLimit
2170                diff.renames
2171                diff.statGraphWidth
2172                diff.submodule
2173                diff.suppressBlankEmpty
2174                diff.tool
2175                diff.wordRegex
2176                diff.algorithm
2177                difftool.
2178                difftool.prompt
2179                fetch.recurseSubmodules
2180                fetch.unpackLimit
2181                format.attach
2182                format.cc
2183                format.coverLetter
2184                format.headers
2185                format.numbered
2186                format.pretty
2187                format.signature
2188                format.signoff
2189                format.subjectprefix
2190                format.suffix
2191                format.thread
2192                format.to
2193                gc.
2194                gc.aggressiveWindow
2195                gc.auto
2196                gc.autopacklimit
2197                gc.packrefs
2198                gc.pruneexpire
2199                gc.reflogexpire
2200                gc.reflogexpireunreachable
2201                gc.rerereresolved
2202                gc.rerereunresolved
2203                gitcvs.allbinary
2204                gitcvs.commitmsgannotation
2205                gitcvs.dbTableNamePrefix
2206                gitcvs.dbdriver
2207                gitcvs.dbname
2208                gitcvs.dbpass
2209                gitcvs.dbuser
2210                gitcvs.enabled
2211                gitcvs.logfile
2212                gitcvs.usecrlfattr
2213                guitool.
2214                gui.blamehistoryctx
2215                gui.commitmsgwidth
2216                gui.copyblamethreshold
2217                gui.diffcontext
2218                gui.encoding
2219                gui.fastcopyblame
2220                gui.matchtrackingbranch
2221                gui.newbranchtemplate
2222                gui.pruneduringfetch
2223                gui.spellingdictionary
2224                gui.trustmtime
2225                help.autocorrect
2226                help.browser
2227                help.format
2228                http.lowSpeedLimit
2229                http.lowSpeedTime
2230                http.maxRequests
2231                http.minSessions
2232                http.noEPSV
2233                http.postBuffer
2234                http.proxy
2235                http.sslCipherList
2236                http.sslVersion
2237                http.sslCAInfo
2238                http.sslCAPath
2239                http.sslCert
2240                http.sslCertPasswordProtected
2241                http.sslKey
2242                http.sslVerify
2243                http.useragent
2244                i18n.commitEncoding
2245                i18n.logOutputEncoding
2246                imap.authMethod
2247                imap.folder
2248                imap.host
2249                imap.pass
2250                imap.port
2251                imap.preformattedHTML
2252                imap.sslverify
2253                imap.tunnel
2254                imap.user
2255                init.templatedir
2256                instaweb.browser
2257                instaweb.httpd
2258                instaweb.local
2259                instaweb.modulepath
2260                instaweb.port
2261                interactive.singlekey
2262                log.date
2263                log.decorate
2264                log.showroot
2265                mailmap.file
2266                man.
2267                man.viewer
2268                merge.
2269                merge.conflictstyle
2270                merge.log
2271                merge.renameLimit
2272                merge.renormalize
2273                merge.stat
2274                merge.tool
2275                merge.verbosity
2276                mergetool.
2277                mergetool.keepBackup
2278                mergetool.keepTemporaries
2279                mergetool.prompt
2280                notes.displayRef
2281                notes.rewrite.
2282                notes.rewrite.amend
2283                notes.rewrite.rebase
2284                notes.rewriteMode
2285                notes.rewriteRef
2286                pack.compression
2287                pack.deltaCacheLimit
2288                pack.deltaCacheSize
2289                pack.depth
2290                pack.indexVersion
2291                pack.packSizeLimit
2292                pack.threads
2293                pack.window
2294                pack.windowMemory
2295                pager.
2296                pretty.
2297                pull.octopus
2298                pull.twohead
2299                push.default
2300                push.followTags
2301                rebase.autosquash
2302                rebase.stat
2303                receive.autogc
2304                receive.denyCurrentBranch
2305                receive.denyDeleteCurrent
2306                receive.denyDeletes
2307                receive.denyNonFastForwards
2308                receive.fsckObjects
2309                receive.unpackLimit
2310                receive.updateserverinfo
2311                remote.pushdefault
2312                remotes.
2313                repack.usedeltabaseoffset
2314                rerere.autoupdate
2315                rerere.enabled
2316                sendemail.
2317                sendemail.aliasesfile
2318                sendemail.aliasfiletype
2319                sendemail.bcc
2320                sendemail.cc
2321                sendemail.cccmd
2322                sendemail.chainreplyto
2323                sendemail.confirm
2324                sendemail.envelopesender
2325                sendemail.from
2326                sendemail.identity
2327                sendemail.multiedit
2328                sendemail.signedoffbycc
2329                sendemail.smtpdomain
2330                sendemail.smtpencryption
2331                sendemail.smtppass
2332                sendemail.smtpserver
2333                sendemail.smtpserveroption
2334                sendemail.smtpserverport
2335                sendemail.smtpuser
2336                sendemail.suppresscc
2337                sendemail.suppressfrom
2338                sendemail.thread
2339                sendemail.to
2340                sendemail.validate
2341                showbranch.default
2342                status.relativePaths
2343                status.showUntrackedFiles
2344                status.submodulesummary
2345                submodule.
2346                tar.umask
2347                transfer.unpackLimit
2348                url.
2349                user.email
2350                user.name
2351                user.signingkey
2352                web.browser
2353                branch. remote.
2354        "
2355}
2356
2357_git_remote ()
2358{
2359        local subcommands="add rename remove set-head set-branches set-url show prune update"
2360        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2361        if [ -z "$subcommand" ]; then
2362                __gitcomp "$subcommands"
2363                return
2364        fi
2365
2366        case "$subcommand" in
2367        rename|remove|set-url|show|prune)
2368                __gitcomp_nl "$(__git_remotes)"
2369                ;;
2370        set-head|set-branches)
2371                __git_complete_remote_or_refspec
2372                ;;
2373        update)
2374                __gitcomp "$(__git_get_config_variables "remotes")"
2375                ;;
2376        *)
2377                ;;
2378        esac
2379}
2380
2381_git_replace ()
2382{
2383        __gitcomp_nl "$(__git_refs)"
2384}
2385
2386_git_reset ()
2387{
2388        __git_has_doubledash && return
2389
2390        case "$cur" in
2391        --*)
2392                __gitcomp "--merge --mixed --hard --soft --patch"
2393                return
2394                ;;
2395        esac
2396        __gitcomp_nl "$(__git_refs)"
2397}
2398
2399_git_revert ()
2400{
2401        local dir="$(__gitdir)"
2402        if [ -f "$dir"/REVERT_HEAD ]; then
2403                __gitcomp "--continue --quit --abort"
2404                return
2405        fi
2406        case "$cur" in
2407        --*)
2408                __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
2409                return
2410                ;;
2411        esac
2412        __gitcomp_nl "$(__git_refs)"
2413}
2414
2415_git_rm ()
2416{
2417        case "$cur" in
2418        --*)
2419                __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
2420                return
2421                ;;
2422        esac
2423
2424        __git_complete_index_file "--cached"
2425}
2426
2427_git_shortlog ()
2428{
2429        __git_has_doubledash && return
2430
2431        case "$cur" in
2432        --*)
2433                __gitcomp "
2434                        $__git_log_common_options
2435                        $__git_log_shortlog_options
2436                        --numbered --summary
2437                        "
2438                return
2439                ;;
2440        esac
2441        __git_complete_revlist
2442}
2443
2444_git_show ()
2445{
2446        __git_has_doubledash && return
2447
2448        case "$cur" in
2449        --pretty=*|--format=*)
2450                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
2451                        " "" "${cur#*=}"
2452                return
2453                ;;
2454        --diff-algorithm=*)
2455                __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
2456                return
2457                ;;
2458        --*)
2459                __gitcomp "--pretty= --format= --abbrev-commit --oneline
2460                        --show-signature
2461                        $__git_diff_common_options
2462                        "
2463                return
2464                ;;
2465        esac
2466        __git_complete_revlist_file
2467}
2468
2469_git_show_branch ()
2470{
2471        case "$cur" in
2472        --*)
2473                __gitcomp "
2474                        --all --remotes --topo-order --date-order --current --more=
2475                        --list --independent --merge-base --no-name
2476                        --color --no-color
2477                        --sha1-name --sparse --topics --reflog
2478                        "
2479                return
2480                ;;
2481        esac
2482        __git_complete_revlist
2483}
2484
2485_git_stash ()
2486{
2487        local save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'
2488        local subcommands='save list show apply clear drop pop create branch'
2489        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2490        if [ -z "$subcommand" ]; then
2491                case "$cur" in
2492                --*)
2493                        __gitcomp "$save_opts"
2494                        ;;
2495                *)
2496                        if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
2497                                __gitcomp "$subcommands"
2498                        fi
2499                        ;;
2500                esac
2501        else
2502                case "$subcommand,$cur" in
2503                save,--*)
2504                        __gitcomp "$save_opts"
2505                        ;;
2506                apply,--*|pop,--*)
2507                        __gitcomp "--index --quiet"
2508                        ;;
2509                drop,--*)
2510                        __gitcomp "--quiet"
2511                        ;;
2512                show,--*|branch,--*)
2513                        ;;
2514                branch,*)
2515                        if [ $cword -eq 3 ]; then
2516                                __gitcomp_nl "$(__git_refs)";
2517                        else
2518                                __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
2519                                                | sed -n -e 's/:.*//p')"
2520                        fi
2521                        ;;
2522                show,*|apply,*|drop,*|pop,*)
2523                        __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
2524                                        | sed -n -e 's/:.*//p')"
2525                        ;;
2526                *)
2527                        ;;
2528                esac
2529        fi
2530}
2531
2532_git_submodule ()
2533{
2534        __git_has_doubledash && return
2535
2536        local subcommands="add status init deinit update summary foreach sync"
2537        if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
2538                case "$cur" in
2539                --*)
2540                        __gitcomp "--quiet --cached"
2541                        ;;
2542                *)
2543                        __gitcomp "$subcommands"
2544                        ;;
2545                esac
2546                return
2547        fi
2548}
2549
2550_git_svn ()
2551{
2552        local subcommands="
2553                init fetch clone rebase dcommit log find-rev
2554                set-tree commit-diff info create-ignore propget
2555                proplist show-ignore show-externals branch tag blame
2556                migrate mkdirs reset gc
2557                "
2558        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2559        if [ -z "$subcommand" ]; then
2560                __gitcomp "$subcommands"
2561        else
2562                local remote_opts="--username= --config-dir= --no-auth-cache"
2563                local fc_opts="
2564                        --follow-parent --authors-file= --repack=
2565                        --no-metadata --use-svm-props --use-svnsync-props
2566                        --log-window-size= --no-checkout --quiet
2567                        --repack-flags --use-log-author --localtime
2568                        --ignore-paths= --include-paths= $remote_opts
2569                        "
2570                local init_opts="
2571                        --template= --shared= --trunk= --tags=
2572                        --branches= --stdlayout --minimize-url
2573                        --no-metadata --use-svm-props --use-svnsync-props
2574                        --rewrite-root= --prefix= --use-log-author
2575                        --add-author-from $remote_opts
2576                        "
2577                local cmt_opts="
2578                        --edit --rmdir --find-copies-harder --copy-similarity=
2579                        "
2580
2581                case "$subcommand,$cur" in
2582                fetch,--*)
2583                        __gitcomp "--revision= --fetch-all $fc_opts"
2584                        ;;
2585                clone,--*)
2586                        __gitcomp "--revision= $fc_opts $init_opts"
2587                        ;;
2588                init,--*)
2589                        __gitcomp "$init_opts"
2590                        ;;
2591                dcommit,--*)
2592                        __gitcomp "
2593                                --merge --strategy= --verbose --dry-run
2594                                --fetch-all --no-rebase --commit-url
2595                                --revision --interactive $cmt_opts $fc_opts
2596                                "
2597                        ;;
2598                set-tree,--*)
2599                        __gitcomp "--stdin $cmt_opts $fc_opts"
2600                        ;;
2601                create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
2602                show-externals,--*|mkdirs,--*)
2603                        __gitcomp "--revision="
2604                        ;;
2605                log,--*)
2606                        __gitcomp "
2607                                --limit= --revision= --verbose --incremental
2608                                --oneline --show-commit --non-recursive
2609                                --authors-file= --color
2610                                "
2611                        ;;
2612                rebase,--*)
2613                        __gitcomp "
2614                                --merge --verbose --strategy= --local
2615                                --fetch-all --dry-run $fc_opts
2616                                "
2617                        ;;
2618                commit-diff,--*)
2619                        __gitcomp "--message= --file= --revision= $cmt_opts"
2620                        ;;
2621                info,--*)
2622                        __gitcomp "--url"
2623                        ;;
2624                branch,--*)
2625                        __gitcomp "--dry-run --message --tag"
2626                        ;;
2627                tag,--*)
2628                        __gitcomp "--dry-run --message"
2629                        ;;
2630                blame,--*)
2631                        __gitcomp "--git-format"
2632                        ;;
2633                migrate,--*)
2634                        __gitcomp "
2635                                --config-dir= --ignore-paths= --minimize
2636                                --no-auth-cache --username=
2637                                "
2638                        ;;
2639                reset,--*)
2640                        __gitcomp "--revision= --parent"
2641                        ;;
2642                *)
2643                        ;;
2644                esac
2645        fi
2646}
2647
2648_git_tag ()
2649{
2650        local i c=1 f=0
2651        while [ $c -lt $cword ]; do
2652                i="${words[c]}"
2653                case "$i" in
2654                -d|-v)
2655                        __gitcomp_nl "$(__git_tags)"
2656                        return
2657                        ;;
2658                -f)
2659                        f=1
2660                        ;;
2661                esac
2662                ((c++))
2663        done
2664
2665        case "$prev" in
2666        -m|-F)
2667                ;;
2668        -*|tag)
2669                if [ $f = 1 ]; then
2670                        __gitcomp_nl "$(__git_tags)"
2671                fi
2672                ;;
2673        *)
2674                __gitcomp_nl "$(__git_refs)"
2675                ;;
2676        esac
2677
2678        case "$cur" in
2679        --*)
2680                __gitcomp "
2681                        --list --delete --verify --annotate --message --file
2682                        --sign --cleanup --local-user --force --column --sort
2683                        --contains --points-at
2684                        "
2685                ;;
2686        esac
2687}
2688
2689_git_whatchanged ()
2690{
2691        _git_log
2692}
2693
2694_git_worktree ()
2695{
2696        local subcommands="add list prune"
2697        local subcommand="$(__git_find_on_cmdline "$subcommands")"
2698        if [ -z "$subcommand" ]; then
2699                __gitcomp "$subcommands"
2700        else
2701                case "$subcommand,$cur" in
2702                add,--*)
2703                        __gitcomp "--detach"
2704                        ;;
2705                list,--*)
2706                        __gitcomp "--porcelain"
2707                        ;;
2708                prune,--*)
2709                        __gitcomp "--dry-run --expire --verbose"
2710                        ;;
2711                *)
2712                        ;;
2713                esac
2714        fi
2715}
2716
2717__git_main ()
2718{
2719        local i c=1 command __git_dir
2720
2721        while [ $c -lt $cword ]; do
2722                i="${words[c]}"
2723                case "$i" in
2724                --git-dir=*) __git_dir="${i#--git-dir=}" ;;
2725                --git-dir)   ((c++)) ; __git_dir="${words[c]}" ;;
2726                --bare)      __git_dir="." ;;
2727                --help) command="help"; break ;;
2728                -c|--work-tree|--namespace) ((c++)) ;;
2729                -*) ;;
2730                *) command="$i"; break ;;
2731                esac
2732                ((c++))
2733        done
2734
2735        if [ -z "$command" ]; then
2736                case "$cur" in
2737                --*)   __gitcomp "
2738                        --paginate
2739                        --no-pager
2740                        --git-dir=
2741                        --bare
2742                        --version
2743                        --exec-path
2744                        --exec-path=
2745                        --html-path
2746                        --man-path
2747                        --info-path
2748                        --work-tree=
2749                        --namespace=
2750                        --no-replace-objects
2751                        --help
2752                        "
2753                        ;;
2754                *)     __git_compute_porcelain_commands
2755                       __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
2756                esac
2757                return
2758        fi
2759
2760        local completion_func="_git_${command//-/_}"
2761        declare -f $completion_func >/dev/null && $completion_func && return
2762
2763        local expansion=$(__git_aliased_command "$command")
2764        if [ -n "$expansion" ]; then
2765                words[1]=$expansion
2766                completion_func="_git_${expansion//-/_}"
2767                declare -f $completion_func >/dev/null && $completion_func
2768        fi
2769}
2770
2771__gitk_main ()
2772{
2773        __git_has_doubledash && return
2774
2775        local g="$(__gitdir)"
2776        local merge=""
2777        if [ -f "$g/MERGE_HEAD" ]; then
2778                merge="--merge"
2779        fi
2780        case "$cur" in
2781        --*)
2782                __gitcomp "
2783                        $__git_log_common_options
2784                        $__git_log_gitk_options
2785                        $merge
2786                        "
2787                return
2788                ;;
2789        esac
2790        __git_complete_revlist
2791}
2792
2793if [[ -n ${ZSH_VERSION-} ]]; then
2794        echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2
2795
2796        autoload -U +X compinit && compinit
2797
2798        __gitcomp ()
2799        {
2800                emulate -L zsh
2801
2802                local cur_="${3-$cur}"
2803
2804                case "$cur_" in
2805                --*=)
2806                        ;;
2807                *)
2808                        local c IFS=$' \t\n'
2809                        local -a array
2810                        for c in ${=1}; do
2811                                c="$c${4-}"
2812                                case $c in
2813                                --*=*|*.) ;;
2814                                *) c="$c " ;;
2815                                esac
2816                                array[${#array[@]}+1]="$c"
2817                        done
2818                        compset -P '*[=:]'
2819                        compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
2820                        ;;
2821                esac
2822        }
2823
2824        __gitcomp_nl ()
2825        {
2826                emulate -L zsh
2827
2828                local IFS=$'\n'
2829                compset -P '*[=:]'
2830                compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
2831        }
2832
2833        __gitcomp_file ()
2834        {
2835                emulate -L zsh
2836
2837                local IFS=$'\n'
2838                compset -P '*[=:]'
2839                compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
2840        }
2841
2842        _git ()
2843        {
2844                local _ret=1 cur cword prev
2845                cur=${words[CURRENT]}
2846                prev=${words[CURRENT-1]}
2847                let cword=CURRENT-1
2848                emulate ksh -c __${service}_main
2849                let _ret && _default && _ret=0
2850                return _ret
2851        }
2852
2853        compdef _git git gitk
2854        return
2855fi
2856
2857__git_func_wrap ()
2858{
2859        local cur words cword prev
2860        _get_comp_words_by_ref -n =: cur words cword prev
2861        $1
2862}
2863
2864# Setup completion for certain functions defined above by setting common
2865# variables and workarounds.
2866# This is NOT a public function; use at your own risk.
2867__git_complete ()
2868{
2869        local wrapper="__git_wrap${2}"
2870        eval "$wrapper () { __git_func_wrap $2 ; }"
2871        complete -o bashdefault -o default -o nospace -F $wrapper $1 2>/dev/null \
2872                || complete -o default -o nospace -F $wrapper $1
2873}
2874
2875# wrapper for backwards compatibility
2876_git ()
2877{
2878        __git_wrap__git_main
2879}
2880
2881# wrapper for backwards compatibility
2882_gitk ()
2883{
2884        __git_wrap__gitk_main
2885}
2886
2887__git_complete git __git_main
2888__git_complete gitk __gitk_main
2889
2890# The following are necessary only for Cygwin, and only are needed
2891# when the user has tab-completed the executable name and consequently
2892# included the '.exe' suffix.
2893#
2894if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
2895__git_complete git.exe __git_main
2896fi