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