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