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