Merge branch 'fc/completion'
authorJunio C Hamano <gitster@pobox.com>
Sun, 2 Jun 2013 22:48:12 +0000 (15:48 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 2 Jun 2013 22:48:12 +0000 (15:48 -0700)
* fc/completion:
completion: remove __git_index_file_list_filter()
completion: add space after completed filename
completion: add hack to enable file mode in bash < 4
completion: refactor __git_complete_index_file()
completion: refactor diff_index wrappers
completion: use __gitcompadd for __gitcomp_file
completion; remove unuseful comments
completion: document tilde expansion failure in tests
completion: add file completion tests

1  2 
contrib/completion/git-completion.bash
index adeff8d9badee3bde9339b90e7b37e5d4dabc305,edb742826691edc7d17508bbec785698690197fb..91234d47ad7f6e3ee0f45d53f67426eeba6bfaf2
@@@ -252,106 -252,50 +252,50 @@@ __gitcomp_file (
        # since tilde expansion is not applied.
        # This means that COMPREPLY will be empty and Bash default
        # completion will be used.
-       COMPREPLY=($(compgen -P "${2-}" -W "$1" -- "${3-$cur}"))
+       __gitcompadd "$1" "${2-}" "${3-$cur}" ""
  
-       # Tell Bash that compspec generates filenames.
-       compopt -o filenames 2>/dev/null
+       # use a hack to enable file mode in bash < 4
+       compopt -o filenames +o nospace 2>/dev/null ||
+       compgen -f /non-existing-dir/ > /dev/null
  }
  
- __git_index_file_list_filter_compat ()
- {
-       local path
-       while read -r path; do
-               case "$path" in
-               ?*/*) echo "${path%%/*}/" ;;
-               *) echo "$path" ;;
-               esac
-       done
- }
- __git_index_file_list_filter_bash ()
- {
-       local path
-       while read -r path; do
-               case "$path" in
-               ?*/*)
-                       # XXX if we append a slash to directory names when using
-                       # `compopt -o filenames`, Bash will append another slash.
-                       # This is pretty stupid, and this the reason why we have to
-                       # define a compatible version for this function.
-                       echo "${path%%/*}" ;;
-               *)
-                       echo "$path" ;;
-               esac
-       done
- }
- # Process path list returned by "ls-files" and "diff-index --name-only"
- # commands, in order to list only file names relative to a specified
- # directory, and append a slash to directory names.
- __git_index_file_list_filter ()
- {
-       # Default to Bash >= 4.x
-       __git_index_file_list_filter_bash
- }
- # Execute git ls-files, returning paths relative to the directory
- # specified in the first argument, and using the options specified in
- # the second argument.
+ # Execute 'git ls-files', unless the --committable option is specified, in
+ # which case it runs 'git diff-index' to find out the files that can be
+ # committed.  It return paths relative to the directory specified in the first
+ # argument, and using the options specified in the second argument.
  __git_ls_files_helper ()
  {
        (
                test -n "${CDPATH+set}" && unset CDPATH
-               # NOTE: $2 is not quoted in order to support multiple options
-               cd "$1" && git ls-files --exclude-standard $2
+               cd "$1"
+               if [ "$2" == "--committable" ]; then
+                       git diff-index --name-only --relative HEAD
+               else
+                       # NOTE: $2 is not quoted in order to support multiple options
+                       git ls-files --exclude-standard $2
+               fi
        ) 2>/dev/null
  }
  
  
- # Execute git diff-index, returning paths relative to the directory
- # specified in the first argument, and using the tree object id
- # specified in the second argument.
- __git_diff_index_helper ()
- {
-       (
-               test -n "${CDPATH+set}" && unset CDPATH
-               cd "$1" && git diff-index --name-only --relative "$2"
-       ) 2>/dev/null
- }
  # __git_index_files accepts 1 or 2 arguments:
  # 1: Options to pass to ls-files (required).
- #    Supported options are --cached, --modified, --deleted, --others,
- #    and --directory.
  # 2: A directory path (optional).
  #    If provided, only files within the specified directory are listed.
  #    Sub directories are never recursed.  Path must have a trailing
  #    slash.
  __git_index_files ()
  {
-       local dir="$(__gitdir)" root="${2-.}"
+       local dir="$(__gitdir)" root="${2-.}" file
  
        if [ -d "$dir" ]; then
-               __git_ls_files_helper "$root" "$1" | __git_index_file_list_filter |
-                       sort | uniq
-       fi
- }
- # __git_diff_index_files accepts 1 or 2 arguments:
- # 1) The id of a tree object.
- # 2) A directory path (optional).
- #    If provided, only files within the specified directory are listed.
- #    Sub directories are never recursed.  Path must have a trailing
- #    slash.
- __git_diff_index_files ()
- {
-       local dir="$(__gitdir)" root="${2-.}"
-       if [ -d "$dir" ]; then
-               __git_diff_index_helper "$root" "$1" | __git_index_file_list_filter |
-                       sort | uniq
+               __git_ls_files_helper "$root" "$1" |
+               while read -r file; do
+                       case "$file" in
+                       ?*/*) echo "${file%%/*}" ;;
+                       *) echo "$file" ;;
+                       esac
+               done | sort | uniq
        fi
  }
  
@@@ -552,44 -496,23 +496,23 @@@ __git_complete_revlist_file (
  }
  
  
- # __git_complete_index_file requires 1 argument: the options to pass to
- # ls-file
+ # __git_complete_index_file requires 1 argument:
+ # 1: the options to pass to ls-file
+ #
+ # The exception is --committable, which finds the files appropriate commit.
  __git_complete_index_file ()
  {
-       local pfx cur_="$cur"
+       local pfx="" cur_="$cur"
  
        case "$cur_" in
        ?*/*)
                pfx="${cur_%/*}"
                cur_="${cur_##*/}"
                pfx="${pfx}/"
-               __gitcomp_file "$(__git_index_files "$1" "$pfx")" "$pfx" "$cur_"
-               ;;
-       *)
-               __gitcomp_file "$(__git_index_files "$1")" "" "$cur_"
                ;;
        esac
- }
  
- # __git_complete_diff_index_file requires 1 argument: the id of a tree
- # object
- __git_complete_diff_index_file ()
- {
-       local pfx cur_="$cur"
-       case "$cur_" in
-       ?*/*)
-               pfx="${cur_%/*}"
-               cur_="${cur_##*/}"
-               pfx="${pfx}/"
-               __gitcomp_file "$(__git_diff_index_files "$1" "$pfx")" "$pfx" "$cur_"
-               ;;
-       *)
-               __gitcomp_file "$(__git_diff_index_files "$1")" "" "$cur_"
-               ;;
-       esac
+       __gitcomp_file "$(__git_index_files "$1" "$pfx")" "$pfx" "$cur_"
  }
  
  __git_complete_file ()
@@@ -1213,7 -1136,7 +1136,7 @@@ _git_commit (
        esac
  
        if git rev-parse --verify --quiet HEAD >/dev/null; then
-               __git_complete_diff_index_file "HEAD"
+               __git_complete_index_file "--committable"
        else
                # This is the first commit
                __git_complete_index_file "--cached"
@@@ -1314,12 -1237,11 +1237,12 @@@ _git_fetch (
  }
  
  __git_format_patch_options="
 -      --stdout --attach --no-attach --thread --thread= --output-directory
 +      --stdout --attach --no-attach --thread --thread= --no-thread
        --numbered --start-number --numbered-files --keep-subject --signoff
        --signature --no-signature --in-reply-to= --cc= --full-index --binary
        --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix=
        --inline --suffix= --ignore-if-in-upstream --subject-prefix=
 +      --output-directory --reroll-count --to= --quiet --notes
  "
  
  _git_format_patch ()
@@@ -1811,7 -1733,7 +1734,7 @@@ __git_config_get_set_variables (
  _git_config ()
  {
        case "$prev" in
 -      branch.*.remote)
 +      branch.*.remote|branch.*.pushremote)
                __gitcomp_nl "$(__git_remotes)"
                return
                ;;
                __gitcomp_nl "$(__git_refs)"
                return
                ;;
 +      branch.*.rebase)
 +              __gitcomp "false true"
 +              return
 +              ;;
 +      remote.pushdefault)
 +              __gitcomp_nl "$(__git_remotes)"
 +              return
 +              ;;
        remote.*.fetch)
                local remote="${prev#remote.}"
                remote="${remote%.fetch}"
                if [ -z "$cur" ]; then
 -                      __gitcompadd "refs/heads/" "" "" ""
 +                      __gitcomp_nl "refs/heads/" "" "" ""
                        return
                fi
                __gitcomp_nl "$(__git_refs_remotes "$remote")"
                        "
                return
                ;;
 +      diff.submodule)
 +              __gitcomp "log short"
 +              return
 +              ;;
        help.format)
                __gitcomp "man info web html"
                return
                ;;
        branch.*.*)
                local pfx="${cur%.*}." cur_="${cur##*.}"
 -              __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur_"
 +              __gitcomp "remote pushremote merge mergeoptions rebase" "$pfx" "$cur_"
                return
                ;;
        branch.*)
                core.whitespace
                core.worktree
                diff.autorefreshindex
 -              diff.statGraphWidth
                diff.external
                diff.ignoreSubmodules
                diff.mnemonicprefix
                diff.noprefix
                diff.renameLimit
                diff.renames
 +              diff.statGraphWidth
 +              diff.submodule
                diff.suppressBlankEmpty
                diff.tool
                diff.wordRegex
                receive.fsckObjects
                receive.unpackLimit
                receive.updateserverinfo
 +              remote.pushdefault
                remotes.
                repack.usedeltabaseoffset
                rerere.autoupdate
@@@ -2451,7 -2359,7 +2374,7 @@@ _git_svn (
                        --no-metadata --use-svm-props --use-svnsync-props
                        --log-window-size= --no-checkout --quiet
                        --repack-flags --use-log-author --localtime
 -                      --ignore-paths= $remote_opts
 +                      --ignore-paths= --include-paths= $remote_opts
                        "
                local init_opts="
                        --template= --shared= --trunk= --tags=
@@@ -2663,7 -2571,7 +2586,7 @@@ if [[ -n ${ZSH_VERSION-} ]]; the
                                --*=*|*.) ;;
                                *) c="$c " ;;
                                esac
 -                              array[$#array+1]="$c"
 +                              array+=("$c")
                        done
                        compset -P '*[=:]'
                        compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
                compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
        }
  
 -      __git_zsh_helper ()
 -      {
 -              emulate -L ksh
 -              local cur cword prev
 -              cur=${words[CURRENT-1]}
 -              prev=${words[CURRENT-2]}
 -              let cword=CURRENT-1
 -              __${service}_main
 -      }
 -
        _git ()
        {
 -              emulate -L zsh
 -              local _ret=1
 -              __git_zsh_helper
 -              let _ret && _default -S '' && _ret=0
 +              local _ret=1 cur cword prev
 +              cur=${words[CURRENT]}
 +              prev=${words[CURRENT-1]}
 +              let cword=CURRENT-1
 +              emulate ksh -c __${service}_main
 +              let _ret && _default && _ret=0
                return _ret
        }
  
        compdef _git git gitk
        return
- elif [[ -n ${BASH_VERSION-} ]]; then
-       if ((${BASH_VERSINFO[0]} < 4)); then
-               # compopt is not supported
-               __git_index_file_list_filter ()
-               {
-                       __git_index_file_list_filter_compat
-               }
-       fi
  fi
  
  __git_func_wrap ()