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