contrib / completion / git-completion.bashon commit completion: remote set-* <name> and <branch> (f1c6ffe)
   1#!bash
   2#
   3# bash/zsh completion support for core Git.
   4#
   5# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
   6# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
   7# Distributed under the GNU General Public License, version 2.0.
   8#
   9# The contained completion routines provide support for completing:
  10#
  11#    *) local and remote branch names
  12#    *) local and remote tag names
  13#    *) .git/remotes file names
  14#    *) git 'subcommands'
  15#    *) tree paths within 'ref:path/to/file' expressions
  16#    *) common --long-options
  17#
  18# To use these routines:
  19#
  20#    1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
  21#    2) Add the following line to your .bashrc/.zshrc:
  22#        source ~/.git-completion.sh
  23#
  24#    3) Consider changing your PS1 to also show the current branch:
  25#         Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
  26#         ZSH:  PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
  27#
  28#       The argument to __git_ps1 will be displayed only if you
  29#       are currently in a git repository.  The %s token will be
  30#       the name of the current branch.
  31#
  32#       In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty
  33#       value, unstaged (*) and staged (+) changes will be shown next
  34#       to the branch name.  You can configure this per-repository
  35#       with the bash.showDirtyState variable, which defaults to true
  36#       once GIT_PS1_SHOWDIRTYSTATE is enabled.
  37#
  38#       You can also see if currently something is stashed, by setting
  39#       GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
  40#       then a '$' will be shown next to the branch name.
  41#
  42#       If you would like to see if there're untracked files, then you can
  43#       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're
  44#       untracked files, then a '%' will be shown next to the branch name.
  45#
  46#       If you would like to see the difference between HEAD and its
  47#       upstream, set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates
  48#       you are behind, ">" indicates you are ahead, and "<>"
  49#       indicates you have diverged.  You can further control
  50#       behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated
  51#       list of values:
  52#           verbose       show number of commits ahead/behind (+/-) upstream
  53#           legacy        don't use the '--count' option available in recent
  54#                         versions of git-rev-list
  55#           git           always compare HEAD to @{upstream}
  56#           svn           always compare HEAD to your SVN upstream
  57#       By default, __git_ps1 will compare HEAD to your SVN upstream
  58#       if it can find one, or @{upstream} otherwise.  Once you have
  59#       set GIT_PS1_SHOWUPSTREAM, you can override it on a
  60#       per-repository basis by setting the bash.showUpstream config
  61#       variable.
  62#
  63
  64if [[ -n ${ZSH_VERSION-} ]]; then
  65        autoload -U +X bashcompinit && bashcompinit
  66fi
  67
  68case "$COMP_WORDBREAKS" in
  69*:*) : great ;;
  70*)   COMP_WORDBREAKS="$COMP_WORDBREAKS:"
  71esac
  72
  73# __gitdir accepts 0 or 1 arguments (i.e., location)
  74# returns location of .git repo
  75__gitdir ()
  76{
  77        if [ -z "${1-}" ]; then
  78                if [ -n "${__git_dir-}" ]; then
  79                        echo "$__git_dir"
  80                elif [ -d .git ]; then
  81                        echo .git
  82                else
  83                        git rev-parse --git-dir 2>/dev/null
  84                fi
  85        elif [ -d "$1/.git" ]; then
  86                echo "$1/.git"
  87        else
  88                echo "$1"
  89        fi
  90}
  91
  92# stores the divergence from upstream in $p
  93# used by GIT_PS1_SHOWUPSTREAM
  94__git_ps1_show_upstream ()
  95{
  96        local key value
  97        local svn_remote=() svn_url_pattern count n
  98        local upstream=git legacy="" verbose=""
  99
 100        # get some config options from git-config
 101        local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
 102        while read -r key value; do
 103                case "$key" in
 104                bash.showupstream)
 105                        GIT_PS1_SHOWUPSTREAM="$value"
 106                        if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
 107                                p=""
 108                                return
 109                        fi
 110                        ;;
 111                svn-remote.*.url)
 112                        svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
 113                        svn_url_pattern+="\\|$value"
 114                        upstream=svn+git # default upstream is SVN if available, else git
 115                        ;;
 116                esac
 117        done <<< "$output"
 118
 119        # parse configuration values
 120        for option in ${GIT_PS1_SHOWUPSTREAM}; do
 121                case "$option" in
 122                git|svn) upstream="$option" ;;
 123                verbose) verbose=1 ;;
 124                legacy)  legacy=1  ;;
 125                esac
 126        done
 127
 128        # Find our upstream
 129        case "$upstream" in
 130        git)    upstream="@{upstream}" ;;
 131        svn*)
 132                # get the upstream from the "git-svn-id: ..." in a commit message
 133                # (git-svn uses essentially the same procedure internally)
 134                local svn_upstream=($(git log --first-parent -1 \
 135                                        --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
 136                if [[ 0 -ne ${#svn_upstream[@]} ]]; then
 137                        svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
 138                        svn_upstream=${svn_upstream%@*}
 139                        local n_stop="${#svn_remote[@]}"
 140                        for ((n=1; n <= n_stop; ++n)); do
 141                                svn_upstream=${svn_upstream#${svn_remote[$n]}}
 142                        done
 143
 144                        if [[ -z "$svn_upstream" ]]; then
 145                                # default branch name for checkouts with no layout:
 146                                upstream=${GIT_SVN_ID:-git-svn}
 147                        else
 148                                upstream=${svn_upstream#/}
 149                        fi
 150                elif [[ "svn+git" = "$upstream" ]]; then
 151                        upstream="@{upstream}"
 152                fi
 153                ;;
 154        esac
 155
 156        # Find how many commits we are ahead/behind our upstream
 157        if [[ -z "$legacy" ]]; then
 158                count="$(git rev-list --count --left-right \
 159                                "$upstream"...HEAD 2>/dev/null)"
 160        else
 161                # produce equivalent output to --count for older versions of git
 162                local commits
 163                if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)"
 164                then
 165                        local commit behind=0 ahead=0
 166                        for commit in $commits
 167                        do
 168                                case "$commit" in
 169                                "<"*) let ++behind
 170                                        ;;
 171                                *)    let ++ahead
 172                                        ;;
 173                                esac
 174                        done
 175                        count="$behind  $ahead"
 176                else
 177                        count=""
 178                fi
 179        fi
 180
 181        # calculate the result
 182        if [[ -z "$verbose" ]]; then
 183                case "$count" in
 184                "") # no upstream
 185                        p="" ;;
 186                "0      0") # equal to upstream
 187                        p="=" ;;
 188                "0      "*) # ahead of upstream
 189                        p=">" ;;
 190                *"      0") # behind upstream
 191                        p="<" ;;
 192                *)          # diverged from upstream
 193                        p="<>" ;;
 194                esac
 195        else
 196                case "$count" in
 197                "") # no upstream
 198                        p="" ;;
 199                "0      0") # equal to upstream
 200                        p=" u=" ;;
 201                "0      "*) # ahead of upstream
 202                        p=" u+${count#0 }" ;;
 203                *"      0") # behind upstream
 204                        p=" u-${count%  0}" ;;
 205                *)          # diverged from upstream
 206                        p=" u+${count#* }-${count%      *}" ;;
 207                esac
 208        fi
 209
 210}
 211
 212
 213# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
 214# returns text to add to bash PS1 prompt (includes branch name)
 215__git_ps1 ()
 216{
 217        local g="$(__gitdir)"
 218        if [ -n "$g" ]; then
 219                local r=""
 220                local b=""
 221                if [ -f "$g/rebase-merge/interactive" ]; then
 222                        r="|REBASE-i"
 223                        b="$(cat "$g/rebase-merge/head-name")"
 224                elif [ -d "$g/rebase-merge" ]; then
 225                        r="|REBASE-m"
 226                        b="$(cat "$g/rebase-merge/head-name")"
 227                else
 228                        if [ -d "$g/rebase-apply" ]; then
 229                                if [ -f "$g/rebase-apply/rebasing" ]; then
 230                                        r="|REBASE"
 231                                elif [ -f "$g/rebase-apply/applying" ]; then
 232                                        r="|AM"
 233                                else
 234                                        r="|AM/REBASE"
 235                                fi
 236                        elif [ -f "$g/MERGE_HEAD" ]; then
 237                                r="|MERGING"
 238                        elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
 239                                r="|CHERRY-PICKING"
 240                        elif [ -f "$g/BISECT_LOG" ]; then
 241                                r="|BISECTING"
 242                        fi
 243
 244                        b="$(git symbolic-ref HEAD 2>/dev/null)" || {
 245
 246                                b="$(
 247                                case "${GIT_PS1_DESCRIBE_STYLE-}" in
 248                                (contains)
 249                                        git describe --contains HEAD ;;
 250                                (branch)
 251                                        git describe --contains --all HEAD ;;
 252                                (describe)
 253                                        git describe HEAD ;;
 254                                (* | default)
 255                                        git describe --tags --exact-match HEAD ;;
 256                                esac 2>/dev/null)" ||
 257
 258                                b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
 259                                b="unknown"
 260                                b="($b)"
 261                        }
 262                fi
 263
 264                local w=""
 265                local i=""
 266                local s=""
 267                local u=""
 268                local c=""
 269                local p=""
 270
 271                if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
 272                        if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
 273                                c="BARE:"
 274                        else
 275                                b="GIT_DIR!"
 276                        fi
 277                elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then
 278                        if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then
 279                                if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then
 280                                        git diff --no-ext-diff --quiet --exit-code || w="*"
 281                                        if git rev-parse --quiet --verify HEAD >/dev/null; then
 282                                                git diff-index --cached --quiet HEAD -- || i="+"
 283                                        else
 284                                                i="#"
 285                                        fi
 286                                fi
 287                        fi
 288                        if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
 289                                git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
 290                        fi
 291
 292                        if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then
 293                                if [ -n "$(git ls-files --others --exclude-standard)" ]; then
 294                                        u="%"
 295                                fi
 296                        fi
 297
 298                        if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
 299                                __git_ps1_show_upstream
 300                        fi
 301                fi
 302
 303                local f="$w$i$s$u"
 304                printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
 305        fi
 306}
 307
 308# __gitcomp_1 requires 2 arguments
 309__gitcomp_1 ()
 310{
 311        local c IFS=' '$'\t'$'\n'
 312        for c in $1; do
 313                case "$c$2" in
 314                --*=*) printf %s$'\n' "$c$2" ;;
 315                *.)    printf %s$'\n' "$c$2" ;;
 316                *)     printf %s$'\n' "$c$2 " ;;
 317                esac
 318        done
 319}
 320
 321# The following function is based on code from:
 322#
 323#   bash_completion - programmable completion functions for bash 3.2+
 324#
 325#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
 326#             © 2009-2010, Bash Completion Maintainers
 327#                     <bash-completion-devel@lists.alioth.debian.org>
 328#
 329#   This program is free software; you can redistribute it and/or modify
 330#   it under the terms of the GNU General Public License as published by
 331#   the Free Software Foundation; either version 2, or (at your option)
 332#   any later version.
 333#
 334#   This program is distributed in the hope that it will be useful,
 335#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 336#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 337#   GNU General Public License for more details.
 338#
 339#   You should have received a copy of the GNU General Public License
 340#   along with this program; if not, write to the Free Software Foundation,
 341#   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 342#
 343#   The latest version of this software can be obtained here:
 344#
 345#   http://bash-completion.alioth.debian.org/
 346#
 347#   RELEASE: 2.x
 348
 349# This function can be used to access a tokenized list of words
 350# on the command line:
 351#
 352#       __git_reassemble_comp_words_by_ref '=:'
 353#       if test "${words_[cword_-1]}" = -w
 354#       then
 355#               ...
 356#       fi
 357#
 358# The argument should be a collection of characters from the list of
 359# word completion separators (COMP_WORDBREAKS) to treat as ordinary
 360# characters.
 361#
 362# This is roughly equivalent to going back in time and setting
 363# COMP_WORDBREAKS to exclude those characters.  The intent is to
 364# make option types like --date=<type> and <rev>:<path> easy to
 365# recognize by treating each shell word as a single token.
 366#
 367# It is best not to set COMP_WORDBREAKS directly because the value is
 368# shared with other completion scripts.  By the time the completion
 369# function gets called, COMP_WORDS has already been populated so local
 370# changes to COMP_WORDBREAKS have no effect.
 371#
 372# Output: words_, cword_, cur_.
 373
 374__git_reassemble_comp_words_by_ref()
 375{
 376        local exclude i j first
 377        # Which word separators to exclude?
 378        exclude="${1//[^$COMP_WORDBREAKS]}"
 379        cword_=$COMP_CWORD
 380        if [ -z "$exclude" ]; then
 381                words_=("${COMP_WORDS[@]}")
 382                return
 383        fi
 384        # List of word completion separators has shrunk;
 385        # re-assemble words to complete.
 386        for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
 387                # Append each nonempty word consisting of just
 388                # word separator characters to the current word.
 389                first=t
 390                while
 391                        [ $i -gt 0 ] &&
 392                        [ -n "${COMP_WORDS[$i]}" ] &&
 393                        # word consists of excluded word separators
 394                        [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
 395                do
 396                        # Attach to the previous token,
 397                        # unless the previous token is the command name.
 398                        if [ $j -ge 2 ] && [ -n "$first" ]; then
 399                                ((j--))
 400                        fi
 401                        first=
 402                        words_[$j]=${words_[j]}${COMP_WORDS[i]}
 403                        if [ $i = $COMP_CWORD ]; then
 404                                cword_=$j
 405                        fi
 406                        if (($i < ${#COMP_WORDS[@]} - 1)); then
 407                                ((i++))
 408                        else
 409                                # Done.
 410                                return
 411                        fi
 412                done
 413                words_[$j]=${words_[j]}${COMP_WORDS[i]}
 414                if [ $i = $COMP_CWORD ]; then
 415                        cword_=$j
 416                fi
 417        done
 418}
 419
 420if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
 421if [[ -z ${ZSH_VERSION:+set} ]]; then
 422_get_comp_words_by_ref ()
 423{
 424        local exclude cur_ words_ cword_
 425        if [ "$1" = "-n" ]; then
 426                exclude=$2
 427                shift 2
 428        fi
 429        __git_reassemble_comp_words_by_ref "$exclude"
 430        cur_=${words_[cword_]}
 431        while [ $# -gt 0 ]; do
 432                case "$1" in
 433                cur)
 434                        cur=$cur_
 435                        ;;
 436                prev)
 437                        prev=${words_[$cword_-1]}
 438                        ;;
 439                words)
 440                        words=("${words_[@]}")
 441                        ;;
 442                cword)
 443                        cword=$cword_
 444                        ;;
 445                esac
 446                shift
 447        done
 448}
 449else
 450_get_comp_words_by_ref ()
 451{
 452        while [ $# -gt 0 ]; do
 453                case "$1" in
 454                cur)
 455                        cur=${COMP_WORDS[COMP_CWORD]}
 456                        ;;
 457                prev)
 458                        prev=${COMP_WORDS[COMP_CWORD-1]}
 459                        ;;
 460                words)
 461                        words=("${COMP_WORDS[@]}")
 462                        ;;
 463                cword)
 464                        cword=$COMP_CWORD
 465                        ;;
 466                -n)
 467                        # assume COMP_WORDBREAKS is already set sanely
 468                        shift
 469                        ;;
 470                esac
 471                shift
 472        done
 473}
 474fi
 475fi
 476
 477# Generates completion reply with compgen, appending a space to possible
 478# completion words, if necessary.
 479# It accepts 1 to 4 arguments:
 480# 1: List of possible completion words.
 481# 2: A prefix to be added to each possible completion word (optional).
 482# 3: Generate possible completion matches for this word (optional).
 483# 4: A suffix to be appended to each possible completion word (optional).
 484__gitcomp ()
 485{
 486        local cur_="${3-$cur}"
 487
 488        case "$cur_" in
 489        --*=)
 490                COMPREPLY=()
 491                ;;
 492        *)
 493                local IFS=$'\n'
 494                COMPREPLY=($(compgen -P "${2-}" \
 495                        -W "$(__gitcomp_1 "${1-}" "${4-}")" \
 496                        -- "$cur_"))
 497                ;;
 498        esac
 499}
 500
 501# Generates completion reply with compgen from newline-separated possible
 502# completion words by appending a space to all of them.
 503# It accepts 1 to 4 arguments:
 504# 1: List of possible completion words, separated by a single newline.
 505# 2: A prefix to be added to each possible completion word (optional).
 506# 3: Generate possible completion matches for this word (optional).
 507# 4: A suffix to be appended to each possible completion word instead of
 508#    the default space (optional).  If specified but empty, nothing is
 509#    appended.
 510__gitcomp_nl ()
 511{
 512        local IFS=$'\n'
 513        COMPREPLY=($(compgen -P "${2-}" -S "${4- }" -W "$1" -- "${3-$cur}"))
 514}
 515
 516__git_heads ()
 517{
 518        local dir="$(__gitdir)"
 519        if [ -d "$dir" ]; then
 520                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
 521                        refs/heads
 522                return
 523        fi
 524}
 525
 526__git_tags ()
 527{
 528        local dir="$(__gitdir)"
 529        if [ -d "$dir" ]; then
 530                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
 531                        refs/tags
 532                return
 533        fi
 534}
 535
 536# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
 537# presence of 2nd argument means use the guess heuristic employed
 538# by checkout for tracking branches
 539__git_refs ()
 540{
 541        local i hash dir="$(__gitdir "${1-}")" track="${2-}"
 542        local format refs
 543        if [ -d "$dir" ]; then
 544                case "$cur" in
 545                refs|refs/*)
 546                        format="refname"
 547                        refs="${cur%/*}"
 548                        track=""
 549                        ;;
 550                *)
 551                        for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
 552                                if [ -e "$dir/$i" ]; then echo $i; fi
 553                        done
 554                        format="refname:short"
 555                        refs="refs/tags refs/heads refs/remotes"
 556                        ;;
 557                esac
 558                git --git-dir="$dir" for-each-ref --format="%($format)" \
 559                        $refs
 560                if [ -n "$track" ]; then
 561                        # employ the heuristic used by git checkout
 562                        # Try to find a remote branch that matches the completion word
 563                        # but only output if the branch name is unique
 564                        local ref entry
 565                        git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \
 566                                "refs/remotes/" | \
 567                        while read -r entry; do
 568                                eval "$entry"
 569                                ref="${ref#*/}"
 570                                if [[ "$ref" == "$cur"* ]]; then
 571                                        echo "$ref"
 572                                fi
 573                        done | uniq -u
 574                fi
 575                return
 576        fi
 577        case "$cur" in
 578        refs|refs/*)
 579                git ls-remote "$dir" "$cur*" 2>/dev/null | \
 580                while read -r hash i; do
 581                        case "$i" in
 582                        *^{}) ;;
 583                        *) echo "$i" ;;
 584                        esac
 585                done
 586                ;;
 587        *)
 588                git ls-remote "$dir" HEAD ORIG_HEAD 'refs/tags/*' 'refs/heads/*' 'refs/remotes/*' 2>/dev/null | \
 589                while read -r hash i; do
 590                        case "$i" in
 591                        *^{}) ;;
 592                        refs/*) echo "${i#refs/*/}" ;;
 593                        *) echo "$i" ;;
 594                        esac
 595                done
 596                ;;
 597        esac
 598}
 599
 600# __git_refs2 requires 1 argument (to pass to __git_refs)
 601__git_refs2 ()
 602{
 603        local i
 604        for i in $(__git_refs "$1"); do
 605                echo "$i:$i"
 606        done
 607}
 608
 609# __git_refs_remotes requires 1 argument (to pass to ls-remote)
 610__git_refs_remotes ()
 611{
 612        local i hash
 613        git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
 614        while read -r hash i; do
 615                echo "$i:refs/remotes/$1/${i#refs/heads/}"
 616        done
 617}
 618
 619__git_remotes ()
 620{
 621        local i IFS=$'\n' d="$(__gitdir)"
 622        test -d "$d/remotes" && ls -1 "$d/remotes"
 623        for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
 624                i="${i#remote.}"
 625                echo "${i/.url*/}"
 626        done
 627}
 628
 629__git_list_merge_strategies ()
 630{
 631        git merge -s help 2>&1 |
 632        sed -n -e '/[Aa]vailable strategies are: /,/^$/{
 633                s/\.$//
 634                s/.*://
 635                s/^[    ]*//
 636                s/[     ]*$//
 637                p
 638        }'
 639}
 640
 641__git_merge_strategies=
 642# 'git merge -s help' (and thus detection of the merge strategy
 643# list) fails, unfortunately, if run outside of any git working
 644# tree.  __git_merge_strategies is set to the empty string in
 645# that case, and the detection will be repeated the next time it
 646# is needed.
 647__git_compute_merge_strategies ()
 648{
 649        test -n "$__git_merge_strategies" ||
 650        __git_merge_strategies=$(__git_list_merge_strategies)
 651}
 652
 653__git_complete_revlist_file ()
 654{
 655        local pfx ls ref cur_="$cur"
 656        case "$cur_" in
 657        *..?*:*)
 658                return
 659                ;;
 660        ?*:*)
 661                ref="${cur_%%:*}"
 662                cur_="${cur_#*:}"
 663                case "$cur_" in
 664                ?*/*)
 665                        pfx="${cur_%/*}"
 666                        cur_="${cur_##*/}"
 667                        ls="$ref:$pfx"
 668                        pfx="$pfx/"
 669                        ;;
 670                *)
 671                        ls="$ref"
 672                        ;;
 673                esac
 674
 675                case "$COMP_WORDBREAKS" in
 676                *:*) : great ;;
 677                *)   pfx="$ref:$pfx" ;;
 678                esac
 679
 680                local IFS=$'\n'
 681                COMPREPLY=($(compgen -P "$pfx" \
 682                        -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
 683                                | sed '/^100... blob /{
 684                                           s,^.*        ,,
 685                                           s,$, ,
 686                                       }
 687                                       /^120000 blob /{
 688                                           s,^.*        ,,
 689                                           s,$, ,
 690                                       }
 691                                       /^040000 tree /{
 692                                           s,^.*        ,,
 693                                           s,$,/,
 694                                       }
 695                                       s/^.*    //')" \
 696                        -- "$cur_"))
 697                ;;
 698        *...*)
 699                pfx="${cur_%...*}..."
 700                cur_="${cur_#*...}"
 701                __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 702                ;;
 703        *..*)
 704                pfx="${cur_%..*}.."
 705                cur_="${cur_#*..}"
 706                __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 707                ;;
 708        *)
 709                __gitcomp_nl "$(__git_refs)"
 710                ;;
 711        esac
 712}
 713
 714
 715__git_complete_file ()
 716{
 717        __git_complete_revlist_file
 718}
 719
 720__git_complete_revlist ()
 721{
 722        __git_complete_revlist_file
 723}
 724
 725__git_complete_remote_or_refspec ()
 726{
 727        local cur_="$cur" cmd="${words[1]}"
 728        local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
 729        if [ "$cmd" = "remote" ]; then
 730                c=$((++c))
 731        fi
 732        while [ $c -lt $cword ]; do
 733                i="${words[c]}"
 734                case "$i" in
 735                --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
 736                --all)
 737                        case "$cmd" in
 738                        push) no_complete_refspec=1 ;;
 739                        fetch)
 740                                COMPREPLY=()
 741                                return
 742                                ;;
 743                        *) ;;
 744                        esac
 745                        ;;
 746                -*) ;;
 747                *) remote="$i"; break ;;
 748                esac
 749                c=$((++c))
 750        done
 751        if [ -z "$remote" ]; then
 752                __gitcomp_nl "$(__git_remotes)"
 753                return
 754        fi
 755        if [ $no_complete_refspec = 1 ]; then
 756                COMPREPLY=()
 757                return
 758        fi
 759        [ "$remote" = "." ] && remote=
 760        case "$cur_" in
 761        *:*)
 762                case "$COMP_WORDBREAKS" in
 763                *:*) : great ;;
 764                *)   pfx="${cur_%%:*}:" ;;
 765                esac
 766                cur_="${cur_#*:}"
 767                lhs=0
 768                ;;
 769        +*)
 770                pfx="+"
 771                cur_="${cur_#+}"
 772                ;;
 773        esac
 774        case "$cmd" in
 775        fetch)
 776                if [ $lhs = 1 ]; then
 777                        __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
 778                else
 779                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 780                fi
 781                ;;
 782        pull|remote)
 783                if [ $lhs = 1 ]; then
 784                        __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
 785                else
 786                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 787                fi
 788                ;;
 789        push)
 790                if [ $lhs = 1 ]; then
 791                        __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
 792                else
 793                        __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
 794                fi
 795                ;;
 796        esac
 797}
 798
 799__git_complete_strategy ()
 800{
 801        __git_compute_merge_strategies
 802        case "$prev" in
 803        -s|--strategy)
 804                __gitcomp "$__git_merge_strategies"
 805                return 0
 806        esac
 807        case "$cur" in
 808        --strategy=*)
 809                __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
 810                return 0
 811                ;;
 812        esac
 813        return 1
 814}
 815
 816__git_list_all_commands ()
 817{
 818        local i IFS=" "$'\n'
 819        for i in $(git help -a|egrep '^  [a-zA-Z0-9]')
 820        do
 821                case $i in
 822                *--*)             : helper pattern;;
 823                *) echo $i;;
 824                esac
 825        done
 826}
 827
 828__git_all_commands=
 829__git_compute_all_commands ()
 830{
 831        test -n "$__git_all_commands" ||
 832        __git_all_commands=$(__git_list_all_commands)
 833}
 834
 835__git_list_porcelain_commands ()
 836{
 837        local i IFS=" "$'\n'
 838        __git_compute_all_commands
 839        for i in "help" $__git_all_commands
 840        do
 841                case $i in
 842                *--*)             : helper pattern;;
 843                applymbox)        : ask gittus;;
 844                applypatch)       : ask gittus;;
 845                archimport)       : import;;
 846                cat-file)         : plumbing;;
 847                check-attr)       : plumbing;;
 848                check-ref-format) : plumbing;;
 849                checkout-index)   : plumbing;;
 850                commit-tree)      : plumbing;;
 851                count-objects)    : infrequent;;
 852                cvsexportcommit)  : export;;
 853                cvsimport)        : import;;
 854                cvsserver)        : daemon;;
 855                daemon)           : daemon;;
 856                diff-files)       : plumbing;;
 857                diff-index)       : plumbing;;
 858                diff-tree)        : plumbing;;
 859                fast-import)      : import;;
 860                fast-export)      : export;;
 861                fsck-objects)     : plumbing;;
 862                fetch-pack)       : plumbing;;
 863                fmt-merge-msg)    : plumbing;;
 864                for-each-ref)     : plumbing;;
 865                hash-object)      : plumbing;;
 866                http-*)           : transport;;
 867                index-pack)       : plumbing;;
 868                init-db)          : deprecated;;
 869                local-fetch)      : plumbing;;
 870                lost-found)       : infrequent;;
 871                ls-files)         : plumbing;;
 872                ls-remote)        : plumbing;;
 873                ls-tree)          : plumbing;;
 874                mailinfo)         : plumbing;;
 875                mailsplit)        : plumbing;;
 876                merge-*)          : plumbing;;
 877                mktree)           : plumbing;;
 878                mktag)            : plumbing;;
 879                pack-objects)     : plumbing;;
 880                pack-redundant)   : plumbing;;
 881                pack-refs)        : plumbing;;
 882                parse-remote)     : plumbing;;
 883                patch-id)         : plumbing;;
 884                peek-remote)      : plumbing;;
 885                prune)            : plumbing;;
 886                prune-packed)     : plumbing;;
 887                quiltimport)      : import;;
 888                read-tree)        : plumbing;;
 889                receive-pack)     : plumbing;;
 890                remote-*)         : transport;;
 891                repo-config)      : deprecated;;
 892                rerere)           : plumbing;;
 893                rev-list)         : plumbing;;
 894                rev-parse)        : plumbing;;
 895                runstatus)        : plumbing;;
 896                sh-setup)         : internal;;
 897                shell)            : daemon;;
 898                show-ref)         : plumbing;;
 899                send-pack)        : plumbing;;
 900                show-index)       : plumbing;;
 901                ssh-*)            : transport;;
 902                stripspace)       : plumbing;;
 903                symbolic-ref)     : plumbing;;
 904                tar-tree)         : deprecated;;
 905                unpack-file)      : plumbing;;
 906                unpack-objects)   : plumbing;;
 907                update-index)     : plumbing;;
 908                update-ref)       : plumbing;;
 909                update-server-info) : daemon;;
 910                upload-archive)   : plumbing;;
 911                upload-pack)      : plumbing;;
 912                write-tree)       : plumbing;;
 913                var)              : infrequent;;
 914                verify-pack)      : infrequent;;
 915                verify-tag)       : plumbing;;
 916                *) echo $i;;
 917                esac
 918        done
 919}
 920
 921__git_porcelain_commands=
 922__git_compute_porcelain_commands ()
 923{
 924        __git_compute_all_commands
 925        test -n "$__git_porcelain_commands" ||
 926        __git_porcelain_commands=$(__git_list_porcelain_commands)
 927}
 928
 929__git_pretty_aliases ()
 930{
 931        local i IFS=$'\n'
 932        for i in $(git --git-dir="$(__gitdir)" config --get-regexp "pretty\..*" 2>/dev/null); do
 933                case "$i" in
 934                pretty.*)
 935                        i="${i#pretty.}"
 936                        echo "${i/ */}"
 937                        ;;
 938                esac
 939        done
 940}
 941
 942__git_aliases ()
 943{
 944        local i IFS=$'\n'
 945        for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
 946                case "$i" in
 947                alias.*)
 948                        i="${i#alias.}"
 949                        echo "${i/ */}"
 950                        ;;
 951                esac
 952        done
 953}
 954
 955# __git_aliased_command requires 1 argument
 956__git_aliased_command ()
 957{
 958        local word cmdline=$(git --git-dir="$(__gitdir)" \
 959                config --get "alias.$1")
 960        for word in $cmdline; do
 961                case "$word" in
 962                \!gitk|gitk)
 963                        echo "gitk"
 964                        return
 965                        ;;
 966                \!*)    : shell command alias ;;
 967                -*)     : option ;;
 968                *=*)    : setting env ;;
 969                git)    : git itself ;;
 970                *)
 971                        echo "$word"
 972                        return
 973                esac
 974        done
 975}
 976
 977# __git_find_on_cmdline requires 1 argument
 978__git_find_on_cmdline ()
 979{
 980        local word subcommand c=1
 981        while [ $c -lt $cword ]; do
 982                word="${words[c]}"
 983                for subcommand in $1; do
 984                        if [ "$subcommand" = "$word" ]; then
 985                                echo "$subcommand"
 986                                return
 987                        fi
 988                done
 989                c=$((++c))
 990        done
 991}
 992
 993__git_has_doubledash ()
 994{
 995        local c=1
 996        while [ $c -lt $cword ]; do
 997                if [ "--" = "${words[c]}" ]; then
 998                        return 0
 999                fi
1000                c=$((++c))
1001        done
1002        return 1
1003}
1004
1005__git_whitespacelist="nowarn warn error error-all fix"
1006
1007_git_am ()
1008{
1009        local dir="$(__gitdir)"
1010        if [ -d "$dir"/rebase-apply ]; then
1011                __gitcomp "--skip --continue --resolved --abort"
1012                return
1013        fi
1014        case "$cur" in
1015        --whitespace=*)
1016                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1017                return
1018                ;;
1019        --*)
1020                __gitcomp "
1021                        --3way --committer-date-is-author-date --ignore-date
1022                        --ignore-whitespace --ignore-space-change
1023                        --interactive --keep --no-utf8 --signoff --utf8
1024                        --whitespace= --scissors
1025                        "
1026                return
1027        esac
1028        COMPREPLY=()
1029}
1030
1031_git_apply ()
1032{
1033        case "$cur" in
1034        --whitespace=*)
1035                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1036                return
1037                ;;
1038        --*)
1039                __gitcomp "
1040                        --stat --numstat --summary --check --index
1041                        --cached --index-info --reverse --reject --unidiff-zero
1042                        --apply --no-add --exclude=
1043                        --ignore-whitespace --ignore-space-change
1044                        --whitespace= --inaccurate-eof --verbose
1045                        "
1046                return
1047        esac
1048        COMPREPLY=()
1049}
1050
1051_git_add ()
1052{
1053        __git_has_doubledash && return
1054
1055        case "$cur" in
1056        --*)
1057                __gitcomp "
1058                        --interactive --refresh --patch --update --dry-run
1059                        --ignore-errors --intent-to-add
1060                        "
1061                return
1062        esac
1063        COMPREPLY=()
1064}
1065
1066_git_archive ()
1067{
1068        case "$cur" in
1069        --format=*)
1070                __gitcomp "$(git archive --list)" "" "${cur##--format=}"
1071                return
1072                ;;
1073        --remote=*)
1074                __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
1075                return
1076                ;;
1077        --*)
1078                __gitcomp "
1079                        --format= --list --verbose
1080                        --prefix= --remote= --exec=
1081                        "
1082                return
1083                ;;
1084        esac
1085        __git_complete_file
1086}
1087
1088_git_bisect ()
1089{
1090        __git_has_doubledash && return
1091
1092        local subcommands="start bad good skip reset visualize replay log run"
1093        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1094        if [ -z "$subcommand" ]; then
1095                if [ -f "$(__gitdir)"/BISECT_START ]; then
1096                        __gitcomp "$subcommands"
1097                else
1098                        __gitcomp "replay start"
1099                fi
1100                return
1101        fi
1102
1103        case "$subcommand" in
1104        bad|good|reset|skip|start)
1105                __gitcomp_nl "$(__git_refs)"
1106                ;;
1107        *)
1108                COMPREPLY=()
1109                ;;
1110        esac
1111}
1112
1113_git_branch ()
1114{
1115        local i c=1 only_local_ref="n" has_r="n"
1116
1117        while [ $c -lt $cword ]; do
1118                i="${words[c]}"
1119                case "$i" in
1120                -d|-m)  only_local_ref="y" ;;
1121                -r)     has_r="y" ;;
1122                esac
1123                c=$((++c))
1124        done
1125
1126        case "$cur" in
1127        --*)
1128                __gitcomp "
1129                        --color --no-color --verbose --abbrev= --no-abbrev
1130                        --track --no-track --contains --merged --no-merged
1131                        --set-upstream --edit-description --list
1132                        "
1133                ;;
1134        *)
1135                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
1136                        __gitcomp_nl "$(__git_heads)"
1137                else
1138                        __gitcomp_nl "$(__git_refs)"
1139                fi
1140                ;;
1141        esac
1142}
1143
1144_git_bundle ()
1145{
1146        local cmd="${words[2]}"
1147        case "$cword" in
1148        2)
1149                __gitcomp "create list-heads verify unbundle"
1150                ;;
1151        3)
1152                # looking for a file
1153                ;;
1154        *)
1155                case "$cmd" in
1156                        create)
1157                                __git_complete_revlist
1158                        ;;
1159                esac
1160                ;;
1161        esac
1162}
1163
1164_git_checkout ()
1165{
1166        __git_has_doubledash && return
1167
1168        case "$cur" in
1169        --conflict=*)
1170                __gitcomp "diff3 merge" "" "${cur##--conflict=}"
1171                ;;
1172        --*)
1173                __gitcomp "
1174                        --quiet --ours --theirs --track --no-track --merge
1175                        --conflict= --orphan --patch
1176                        "
1177                ;;
1178        *)
1179                # check if --track, --no-track, or --no-guess was specified
1180                # if so, disable DWIM mode
1181                local flags="--track --no-track --no-guess" track=1
1182                if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
1183                        track=''
1184                fi
1185                __gitcomp_nl "$(__git_refs '' $track)"
1186                ;;
1187        esac
1188}
1189
1190_git_cherry ()
1191{
1192        __gitcomp "$(__git_refs)"
1193}
1194
1195_git_cherry_pick ()
1196{
1197        case "$cur" in
1198        --*)
1199                __gitcomp "--edit --no-commit"
1200                ;;
1201        *)
1202                __gitcomp_nl "$(__git_refs)"
1203                ;;
1204        esac
1205}
1206
1207_git_clean ()
1208{
1209        __git_has_doubledash && return
1210
1211        case "$cur" in
1212        --*)
1213                __gitcomp "--dry-run --quiet"
1214                return
1215                ;;
1216        esac
1217        COMPREPLY=()
1218}
1219
1220_git_clone ()
1221{
1222        case "$cur" in
1223        --*)
1224                __gitcomp "
1225                        --local
1226                        --no-hardlinks
1227                        --shared
1228                        --reference
1229                        --quiet
1230                        --no-checkout
1231                        --bare
1232                        --mirror
1233                        --origin
1234                        --upload-pack
1235                        --template=
1236                        --depth
1237                        "
1238                return
1239                ;;
1240        esac
1241        COMPREPLY=()
1242}
1243
1244_git_commit ()
1245{
1246        __git_has_doubledash && return
1247
1248        case "$cur" in
1249        --cleanup=*)
1250                __gitcomp "default strip verbatim whitespace
1251                        " "" "${cur##--cleanup=}"
1252                return
1253                ;;
1254        --reuse-message=*|--reedit-message=*|\
1255        --fixup=*|--squash=*)
1256                __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1257                return
1258                ;;
1259        --untracked-files=*)
1260                __gitcomp "all no normal" "" "${cur##--untracked-files=}"
1261                return
1262                ;;
1263        --*)
1264                __gitcomp "
1265                        --all --author= --signoff --verify --no-verify
1266                        --edit --amend --include --only --interactive
1267                        --dry-run --reuse-message= --reedit-message=
1268                        --reset-author --file= --message= --template=
1269                        --cleanup= --untracked-files --untracked-files=
1270                        --verbose --quiet --fixup= --squash=
1271                        "
1272                return
1273        esac
1274        COMPREPLY=()
1275}
1276
1277_git_describe ()
1278{
1279        case "$cur" in
1280        --*)
1281                __gitcomp "
1282                        --all --tags --contains --abbrev= --candidates=
1283                        --exact-match --debug --long --match --always
1284                        "
1285                return
1286        esac
1287        __gitcomp_nl "$(__git_refs)"
1288}
1289
1290__git_diff_common_options="--stat --numstat --shortstat --summary
1291                        --patch-with-stat --name-only --name-status --color
1292                        --no-color --color-words --no-renames --check
1293                        --full-index --binary --abbrev --diff-filter=
1294                        --find-copies-harder
1295                        --text --ignore-space-at-eol --ignore-space-change
1296                        --ignore-all-space --exit-code --quiet --ext-diff
1297                        --no-ext-diff
1298                        --no-prefix --src-prefix= --dst-prefix=
1299                        --inter-hunk-context=
1300                        --patience
1301                        --raw
1302                        --dirstat --dirstat= --dirstat-by-file
1303                        --dirstat-by-file= --cumulative
1304"
1305
1306_git_diff ()
1307{
1308        __git_has_doubledash && return
1309
1310        case "$cur" in
1311        --*)
1312                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1313                        --base --ours --theirs --no-index
1314                        $__git_diff_common_options
1315                        "
1316                return
1317                ;;
1318        esac
1319        __git_complete_revlist_file
1320}
1321
1322__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
1323                        tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc3
1324"
1325
1326_git_difftool ()
1327{
1328        __git_has_doubledash && return
1329
1330        case "$cur" in
1331        --tool=*)
1332                __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
1333                return
1334                ;;
1335        --*)
1336                __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
1337                        --base --ours --theirs
1338                        --no-renames --diff-filter= --find-copies-harder
1339                        --relative --ignore-submodules
1340                        --tool="
1341                return
1342                ;;
1343        esac
1344        __git_complete_file
1345}
1346
1347__git_fetch_options="
1348        --quiet --verbose --append --upload-pack --force --keep --depth=
1349        --tags --no-tags --all --prune --dry-run
1350"
1351
1352_git_fetch ()
1353{
1354        case "$cur" in
1355        --*)
1356                __gitcomp "$__git_fetch_options"
1357                return
1358                ;;
1359        esac
1360        __git_complete_remote_or_refspec
1361}
1362
1363_git_format_patch ()
1364{
1365        case "$cur" in
1366        --thread=*)
1367                __gitcomp "
1368                        deep shallow
1369                        " "" "${cur##--thread=}"
1370                return
1371                ;;
1372        --*)
1373                __gitcomp "
1374                        --stdout --attach --no-attach --thread --thread=
1375                        --output-directory
1376                        --numbered --start-number
1377                        --numbered-files
1378                        --keep-subject
1379                        --signoff --signature --no-signature
1380                        --in-reply-to= --cc=
1381                        --full-index --binary
1382                        --not --all
1383                        --cover-letter
1384                        --no-prefix --src-prefix= --dst-prefix=
1385                        --inline --suffix= --ignore-if-in-upstream
1386                        --subject-prefix=
1387                        "
1388                return
1389                ;;
1390        esac
1391        __git_complete_revlist
1392}
1393
1394_git_fsck ()
1395{
1396        case "$cur" in
1397        --*)
1398                __gitcomp "
1399                        --tags --root --unreachable --cache --no-reflogs --full
1400                        --strict --verbose --lost-found
1401                        "
1402                return
1403                ;;
1404        esac
1405        COMPREPLY=()
1406}
1407
1408_git_gc ()
1409{
1410        case "$cur" in
1411        --*)
1412                __gitcomp "--prune --aggressive"
1413                return
1414                ;;
1415        esac
1416        COMPREPLY=()
1417}
1418
1419_git_gitk ()
1420{
1421        _gitk
1422}
1423
1424__git_match_ctag() {
1425        awk "/^${1////\\/}/ { print \$1 }" "$2"
1426}
1427
1428_git_grep ()
1429{
1430        __git_has_doubledash && return
1431
1432        case "$cur" in
1433        --*)
1434                __gitcomp "
1435                        --cached
1436                        --text --ignore-case --word-regexp --invert-match
1437                        --full-name --line-number
1438                        --extended-regexp --basic-regexp --fixed-strings
1439                        --perl-regexp
1440                        --files-with-matches --name-only
1441                        --files-without-match
1442                        --max-depth
1443                        --count
1444                        --and --or --not --all-match
1445                        "
1446                return
1447                ;;
1448        esac
1449
1450        case "$cword,$prev" in
1451        2,*|*,-*)
1452                if test -r tags; then
1453                        __gitcomp_nl "$(__git_match_ctag "$cur" tags)"
1454                        return
1455                fi
1456                ;;
1457        esac
1458
1459        __gitcomp_nl "$(__git_refs)"
1460}
1461
1462_git_help ()
1463{
1464        case "$cur" in
1465        --*)
1466                __gitcomp "--all --info --man --web"
1467                return
1468                ;;
1469        esac
1470        __git_compute_all_commands
1471        __gitcomp "$__git_all_commands $(__git_aliases)
1472                attributes cli core-tutorial cvs-migration
1473                diffcore gitk glossary hooks ignore modules
1474                namespaces repository-layout tutorial tutorial-2
1475                workflows
1476                "
1477}
1478
1479_git_init ()
1480{
1481        case "$cur" in
1482        --shared=*)
1483                __gitcomp "
1484                        false true umask group all world everybody
1485                        " "" "${cur##--shared=}"
1486                return
1487                ;;
1488        --*)
1489                __gitcomp "--quiet --bare --template= --shared --shared="
1490                return
1491                ;;
1492        esac
1493        COMPREPLY=()
1494}
1495
1496_git_ls_files ()
1497{
1498        __git_has_doubledash && return
1499
1500        case "$cur" in
1501        --*)
1502                __gitcomp "--cached --deleted --modified --others --ignored
1503                        --stage --directory --no-empty-directory --unmerged
1504                        --killed --exclude= --exclude-from=
1505                        --exclude-per-directory= --exclude-standard
1506                        --error-unmatch --with-tree= --full-name
1507                        --abbrev --ignored --exclude-per-directory
1508                        "
1509                return
1510                ;;
1511        esac
1512        COMPREPLY=()
1513}
1514
1515_git_ls_remote ()
1516{
1517        __gitcomp_nl "$(__git_remotes)"
1518}
1519
1520_git_ls_tree ()
1521{
1522        __git_complete_file
1523}
1524
1525# Options that go well for log, shortlog and gitk
1526__git_log_common_options="
1527        --not --all
1528        --branches --tags --remotes
1529        --first-parent --merges --no-merges
1530        --max-count=
1531        --max-age= --since= --after=
1532        --min-age= --until= --before=
1533        --min-parents= --max-parents=
1534        --no-min-parents --no-max-parents
1535"
1536# Options that go well for log and gitk (not shortlog)
1537__git_log_gitk_options="
1538        --dense --sparse --full-history
1539        --simplify-merges --simplify-by-decoration
1540        --left-right --notes --no-notes
1541"
1542# Options that go well for log and shortlog (not gitk)
1543__git_log_shortlog_options="
1544        --author= --committer= --grep=
1545        --all-match
1546"
1547
1548__git_log_pretty_formats="oneline short medium full fuller email raw format:"
1549__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
1550
1551_git_log ()
1552{
1553        __git_has_doubledash && return
1554
1555        local g="$(git rev-parse --git-dir 2>/dev/null)"
1556        local merge=""
1557        if [ -f "$g/MERGE_HEAD" ]; then
1558                merge="--merge"
1559        fi
1560        case "$cur" in
1561        --pretty=*|--format=*)
1562                __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
1563                        " "" "${cur#*=}"
1564                return
1565                ;;
1566        --date=*)
1567                __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
1568                return
1569                ;;
1570        --decorate=*)
1571                __gitcomp "long short" "" "${cur##--decorate=}"
1572                return
1573                ;;
1574        --*)
1575                __gitcomp "
1576                        $__git_log_common_options
1577                        $__git_log_shortlog_options
1578                        $__git_log_gitk_options
1579                        --root --topo-order --date-order --reverse
1580                        --follow --full-diff
1581                        --abbrev-commit --abbrev=
1582                        --relative-date --date=
1583                        --pretty= --format= --oneline
1584                        --cherry-pick
1585                        --graph
1586                        --decorate --decorate=
1587                        --walk-reflogs
1588                        --parents --children
1589                        $merge
1590                        $__git_diff_common_options
1591                        --pickaxe-all --pickaxe-regex
1592                        "
1593                return
1594                ;;
1595        esac
1596        __git_complete_revlist
1597}
1598
1599__git_merge_options="
1600        --no-commit --no-stat --log --no-log --squash --strategy
1601        --commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit
1602"
1603
1604_git_merge ()
1605{
1606        __git_complete_strategy && return
1607
1608        case "$cur" in
1609        --*)
1610                __gitcomp "$__git_merge_options"
1611                return
1612        esac
1613        __gitcomp_nl "$(__git_refs)"
1614}
1615
1616_git_mergetool ()
1617{
1618        case "$cur" in
1619        --tool=*)
1620                __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
1621                return
1622                ;;
1623        --*)
1624                __gitcomp "--tool="
1625                return
1626                ;;
1627        esac
1628        COMPREPLY=()
1629}
1630
1631_git_merge_base ()
1632{
1633        __gitcomp_nl "$(__git_refs)"
1634}
1635
1636_git_mv ()
1637{
1638        case "$cur" in
1639        --*)
1640                __gitcomp "--dry-run"
1641                return
1642                ;;
1643        esac
1644        COMPREPLY=()
1645}
1646
1647_git_name_rev ()
1648{
1649        __gitcomp "--tags --all --stdin"
1650}
1651
1652_git_notes ()
1653{
1654        local subcommands='add append copy edit list prune remove show'
1655        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1656
1657        case "$subcommand,$cur" in
1658        ,--*)
1659                __gitcomp '--ref'
1660                ;;
1661        ,*)
1662                case "${words[cword-1]}" in
1663                --ref)
1664                        __gitcomp_nl "$(__git_refs)"
1665                        ;;
1666                *)
1667                        __gitcomp "$subcommands --ref"
1668                        ;;
1669                esac
1670                ;;
1671        add,--reuse-message=*|append,--reuse-message=*|\
1672        add,--reedit-message=*|append,--reedit-message=*)
1673                __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
1674                ;;
1675        add,--*|append,--*)
1676                __gitcomp '--file= --message= --reedit-message=
1677                                --reuse-message='
1678                ;;
1679        copy,--*)
1680                __gitcomp '--stdin'
1681                ;;
1682        prune,--*)
1683                __gitcomp '--dry-run --verbose'
1684                ;;
1685        prune,*)
1686                ;;
1687        *)
1688                case "${words[cword-1]}" in
1689                -m|-F)
1690                        ;;
1691                *)
1692                        __gitcomp_nl "$(__git_refs)"
1693                        ;;
1694                esac
1695                ;;
1696        esac
1697}
1698
1699_git_pull ()
1700{
1701        __git_complete_strategy && return
1702
1703        case "$cur" in
1704        --*)
1705                __gitcomp "
1706                        --rebase --no-rebase
1707                        $__git_merge_options
1708                        $__git_fetch_options
1709                "
1710                return
1711                ;;
1712        esac
1713        __git_complete_remote_or_refspec
1714}
1715
1716_git_push ()
1717{
1718        case "$prev" in
1719        --repo)
1720                __gitcomp_nl "$(__git_remotes)"
1721                return
1722        esac
1723        case "$cur" in
1724        --repo=*)
1725                __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
1726                return
1727                ;;
1728        --*)
1729                __gitcomp "
1730                        --all --mirror --tags --dry-run --force --verbose
1731                        --receive-pack= --repo= --set-upstream
1732                "
1733                return
1734                ;;
1735        esac
1736        __git_complete_remote_or_refspec
1737}
1738
1739_git_rebase ()
1740{
1741        local dir="$(__gitdir)"
1742        if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1743                __gitcomp "--continue --skip --abort"
1744                return
1745        fi
1746        __git_complete_strategy && return
1747        case "$cur" in
1748        --whitespace=*)
1749                __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
1750                return
1751                ;;
1752        --*)
1753                __gitcomp "
1754                        --onto --merge --strategy --interactive
1755                        --preserve-merges --stat --no-stat
1756                        --committer-date-is-author-date --ignore-date
1757                        --ignore-whitespace --whitespace=
1758                        --autosquash
1759                        "
1760
1761                return
1762        esac
1763        __gitcomp_nl "$(__git_refs)"
1764}
1765
1766_git_reflog ()
1767{
1768        local subcommands="show delete expire"
1769        local subcommand="$(__git_find_on_cmdline "$subcommands")"
1770
1771        if [ -z "$subcommand" ]; then
1772                __gitcomp "$subcommands"
1773        else
1774                __gitcomp_nl "$(__git_refs)"
1775        fi
1776}
1777
1778__git_send_email_confirm_options="always never auto cc compose"
1779__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
1780
1781_git_send_email ()
1782{
1783        case "$cur" in
1784        --confirm=*)
1785                __gitcomp "
1786                        $__git_send_email_confirm_options
1787                        " "" "${cur##--confirm=}"
1788                return
1789                ;;
1790        --suppress-cc=*)
1791                __gitcomp "
1792                        $__git_send_email_suppresscc_options
1793                        " "" "${cur##--suppress-cc=}"
1794
1795                return
1796                ;;
1797        --smtp-encryption=*)
1798                __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
1799                return
1800                ;;
1801        --*)
1802                __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
1803                        --compose --confirm= --dry-run --envelope-sender
1804                        --from --identity
1805                        --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1806                        --no-suppress-from --no-thread --quiet
1807                        --signed-off-by-cc --smtp-pass --smtp-server
1808                        --smtp-server-port --smtp-encryption= --smtp-user
1809                        --subject --suppress-cc= --suppress-from --thread --to
1810                        --validate --no-validate"
1811                return
1812                ;;
1813        esac
1814        COMPREPLY=()
1815}
1816
1817_git_stage ()
1818{
1819        _git_add
1820}
1821
1822__git_config_get_set_variables ()
1823{
1824        local prevword word config_file= c=$cword
1825        while [ $c -gt 1 ]; do
1826                word="${words[c]}"
1827                case "$word" in
1828                --global|--system|--file=*)
1829                        config_file="$word"
1830                        break
1831                        ;;
1832                -f|--file)
1833                        config_file="$word $prevword"
1834                        break
1835                        ;;
1836                esac
1837                prevword=$word
1838                c=$((--c))
1839        done
1840
1841        git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null |
1842        while read -r line
1843        do
1844                case "$line" in
1845                *.*=*)
1846                        echo "${line/=*/}"
1847                        ;;
1848                esac
1849        done
1850}
1851
1852_git_config ()
1853{
1854        case "$prev" in
1855        branch.*.remote)
1856                __gitcomp_nl "$(__git_remotes)"
1857                return
1858                ;;
1859        branch.*.merge)
1860                __gitcomp_nl "$(__git_refs)"
1861                return
1862                ;;
1863        remote.*.fetch)
1864                local remote="${prev#remote.}"
1865                remote="${remote%.fetch}"
1866                if [ -z "$cur" ]; then
1867                        COMPREPLY=("refs/heads/")
1868                        return
1869                fi
1870                __gitcomp_nl "$(__git_refs_remotes "$remote")"
1871                return
1872                ;;
1873        remote.*.push)
1874                local remote="${prev#remote.}"
1875                remote="${remote%.push}"
1876                __gitcomp_nl "$(git --git-dir="$(__gitdir)" \
1877                        for-each-ref --format='%(refname):%(refname)' \
1878                        refs/heads)"
1879                return
1880                ;;
1881        pull.twohead|pull.octopus)
1882                __git_compute_merge_strategies
1883                __gitcomp "$__git_merge_strategies"
1884                return
1885                ;;
1886        color.branch|color.diff|color.interactive|\
1887        color.showbranch|color.status|color.ui)
1888                __gitcomp "always never auto"
1889                return
1890                ;;
1891        color.pager)
1892                __gitcomp "false true"
1893                return
1894                ;;
1895        color.*.*)
1896                __gitcomp "
1897                        normal black red green yellow blue magenta cyan white
1898                        bold dim ul blink reverse
1899                        "
1900                return
1901                ;;
1902        help.format)
1903                __gitcomp "man info web html"
1904                return
1905                ;;
1906        log.date)
1907                __gitcomp "$__git_log_date_formats"
1908                return
1909                ;;
1910        sendemail.aliasesfiletype)
1911                __gitcomp "mutt mailrc pine elm gnus"
1912                return
1913                ;;
1914        sendemail.confirm)
1915                __gitcomp "$__git_send_email_confirm_options"
1916                return
1917                ;;
1918        sendemail.suppresscc)
1919                __gitcomp "$__git_send_email_suppresscc_options"
1920                return
1921                ;;
1922        --get|--get-all|--unset|--unset-all)
1923                __gitcomp_nl "$(__git_config_get_set_variables)"
1924                return
1925                ;;
1926        *.*)
1927                COMPREPLY=()
1928                return
1929                ;;
1930        esac
1931        case "$cur" in
1932        --*)
1933                __gitcomp "
1934                        --global --system --file=
1935                        --list --replace-all
1936                        --get --get-all --get-regexp
1937                        --add --unset --unset-all
1938                        --remove-section --rename-section
1939                        "
1940                return
1941                ;;
1942        branch.*.*)
1943                local pfx="${cur%.*}." cur_="${cur##*.}"
1944                __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur_"
1945                return
1946                ;;
1947        branch.*)
1948                local pfx="${cur%.*}." cur_="${cur#*.}"
1949                __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
1950                return
1951                ;;
1952        guitool.*.*)
1953                local pfx="${cur%.*}." cur_="${cur##*.}"
1954                __gitcomp "
1955                        argprompt cmd confirm needsfile noconsole norescan
1956                        prompt revprompt revunmerged title
1957                        " "$pfx" "$cur_"
1958                return
1959                ;;
1960        difftool.*.*)
1961                local pfx="${cur%.*}." cur_="${cur##*.}"
1962                __gitcomp "cmd path" "$pfx" "$cur_"
1963                return
1964                ;;
1965        man.*.*)
1966                local pfx="${cur%.*}." cur_="${cur##*.}"
1967                __gitcomp "cmd path" "$pfx" "$cur_"
1968                return
1969                ;;
1970        mergetool.*.*)
1971                local pfx="${cur%.*}." cur_="${cur##*.}"
1972                __gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
1973                return
1974                ;;
1975        pager.*)
1976                local pfx="${cur%.*}." cur_="${cur#*.}"
1977                __git_compute_all_commands
1978                __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
1979                return
1980                ;;
1981        remote.*.*)
1982                local pfx="${cur%.*}." cur_="${cur##*.}"
1983                __gitcomp "
1984                        url proxy fetch push mirror skipDefaultUpdate
1985                        receivepack uploadpack tagopt pushurl
1986                        " "$pfx" "$cur_"
1987                return
1988                ;;
1989        remote.*)
1990                local pfx="${cur%.*}." cur_="${cur#*.}"
1991                __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
1992                return
1993                ;;
1994        url.*.*)
1995                local pfx="${cur%.*}." cur_="${cur##*.}"
1996                __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
1997                return
1998                ;;
1999        esac
2000        __gitcomp "
2001                add.ignoreErrors
2002                advice.commitBeforeMerge
2003                advice.detachedHead
2004                advice.implicitIdentity
2005                advice.pushNonFastForward
2006                advice.resolveConflict
2007                advice.statusHints
2008                alias.
2009                am.keepcr
2010                apply.ignorewhitespace
2011                apply.whitespace
2012                branch.autosetupmerge
2013                branch.autosetuprebase
2014                browser.
2015                clean.requireForce
2016                color.branch
2017                color.branch.current
2018                color.branch.local
2019                color.branch.plain
2020                color.branch.remote
2021                color.decorate.HEAD
2022                color.decorate.branch
2023                color.decorate.remoteBranch
2024                color.decorate.stash
2025                color.decorate.tag
2026                color.diff
2027                color.diff.commit
2028                color.diff.frag
2029                color.diff.func
2030                color.diff.meta
2031                color.diff.new
2032                color.diff.old
2033                color.diff.plain
2034                color.diff.whitespace
2035                color.grep
2036                color.grep.context
2037                color.grep.filename
2038                color.grep.function
2039                color.grep.linenumber
2040                color.grep.match
2041                color.grep.selected
2042                color.grep.separator
2043                color.interactive
2044                color.interactive.error
2045                color.interactive.header
2046                color.interactive.help
2047                color.interactive.prompt
2048                color.pager
2049                color.showbranch
2050                color.status
2051                color.status.added
2052                color.status.changed
2053                color.status.header
2054                color.status.nobranch
2055                color.status.untracked
2056                color.status.updated
2057                color.ui
2058                commit.status
2059                commit.template
2060                core.abbrev
2061                core.askpass
2062                core.attributesfile
2063                core.autocrlf
2064                core.bare
2065                core.bigFileThreshold
2066                core.compression
2067                core.createObject
2068                core.deltaBaseCacheLimit
2069                core.editor
2070                core.eol
2071                core.excludesfile
2072                core.fileMode
2073                core.fsyncobjectfiles
2074                core.gitProxy
2075                core.ignoreCygwinFSTricks
2076                core.ignoreStat
2077                core.ignorecase
2078                core.logAllRefUpdates
2079                core.loosecompression
2080                core.notesRef
2081                core.packedGitLimit
2082                core.packedGitWindowSize
2083                core.pager
2084                core.preferSymlinkRefs
2085                core.preloadindex
2086                core.quotepath
2087                core.repositoryFormatVersion
2088                core.safecrlf
2089                core.sharedRepository
2090                core.sparseCheckout
2091                core.symlinks
2092                core.trustctime
2093                core.warnAmbiguousRefs
2094                core.whitespace
2095                core.worktree
2096                diff.autorefreshindex
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 $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=$((++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=$((++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