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