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