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