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