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