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