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