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