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