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