From: Junio C Hamano Date: Thu, 28 Jun 2012 22:21:00 +0000 (-0700) Subject: Merge branch 'fc/git-prompt-script' X-Git-Tag: v1.7.12-rc0~67 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/e90020cdb3273af3b0c7915c0aacf16b19bbf994?ds=inline;hp=-c Merge branch 'fc/git-prompt-script' Split a rather heavy-ish "git completion" script out to create a separate "git prompting" script, to help lazy-autoloading of the completion part while making prompting part always available. --- e90020cdb3273af3b0c7915c0aacf16b19bbf994 diff --combined contrib/completion/git-completion.bash index 2e1b5e14b9,5d70cc4286..ffedce751c mode 100755,100644..100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@@ -20,46 -20,8 +20,8 @@@ # 1) Copy this file to somewhere (e.g. ~/.git-completion.sh). # 2) Add the following line to your .bashrc/.zshrc: # source ~/.git-completion.sh - # - # 3) Consider changing your PS1 to also show the current branch: - # Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' - # ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' - # - # The argument to __git_ps1 will be displayed only if you - # are currently in a git repository. The %s token will be - # the name of the current branch. - # - # In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty - # value, unstaged (*) and staged (+) changes will be shown next - # to the branch name. You can configure this per-repository - # with the bash.showDirtyState variable, which defaults to true - # once GIT_PS1_SHOWDIRTYSTATE is enabled. - # - # You can also see if currently something is stashed, by setting - # GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, - # then a '$' will be shown next to the branch name. - # - # If you would like to see if there're untracked files, then you can - # set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're - # untracked files, then a '%' will be shown next to the branch name. - # - # If you would like to see the difference between HEAD and its - # upstream, set GIT_PS1_SHOWUPSTREAM="auto". A "<" indicates - # you are behind, ">" indicates you are ahead, and "<>" - # indicates you have diverged. You can further control - # behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated - # list of values: - # verbose show number of commits ahead/behind (+/-) upstream - # legacy don't use the '--count' option available in recent - # versions of git-rev-list - # git always compare HEAD to @{upstream} - # svn always compare HEAD to your SVN upstream - # By default, __git_ps1 will compare HEAD to your SVN upstream - # if it can find one, or @{upstream} otherwise. Once you have - # set GIT_PS1_SHOWUPSTREAM, you can override it on a - # per-repository basis by setting the bash.showUpstream config - # variable. - # + # 3) Consider changing your PS1 to also show the current branch, + # see git-prompt.sh for details. if [[ -n ${ZSH_VERSION-} ]]; then autoload -U +X bashcompinit && bashcompinit @@@ -74,9 -36,14 +36,14 @@@ esa # returns location of .git repo __gitdir () { + # Note: this function is duplicated in git-prompt.sh + # When updating it, make sure you update the other one to match. if [ -z "${1-}" ]; then if [ -n "${__git_dir-}" ]; then echo "$__git_dir" + elif [ -n "${GIT_DIR-}" ]; then + test -d "${GIT_DIR-}" || return 1 + echo "$GIT_DIR" elif [ -d .git ]; then echo .git else @@@ -89,221 -56,6 +56,6 @@@ fi } - # stores the divergence from upstream in $p - # used by GIT_PS1_SHOWUPSTREAM - __git_ps1_show_upstream () - { - local key value - local svn_remote svn_url_pattern count n - local upstream=git legacy="" verbose="" - - svn_remote=() - # get some config options from git-config - local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')" - while read -r key value; do - case "$key" in - bash.showupstream) - GIT_PS1_SHOWUPSTREAM="$value" - if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then - p="" - return - fi - ;; - svn-remote.*.url) - svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value" - svn_url_pattern+="\\|$value" - upstream=svn+git # default upstream is SVN if available, else git - ;; - esac - done <<< "$output" - - # parse configuration values - for option in ${GIT_PS1_SHOWUPSTREAM}; do - case "$option" in - git|svn) upstream="$option" ;; - verbose) verbose=1 ;; - legacy) legacy=1 ;; - esac - done - - # Find our upstream - case "$upstream" in - git) upstream="@{upstream}" ;; - svn*) - # get the upstream from the "git-svn-id: ..." in a commit message - # (git-svn uses essentially the same procedure internally) - local svn_upstream=($(git log --first-parent -1 \ - --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null)) - if [[ 0 -ne ${#svn_upstream[@]} ]]; then - svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} - svn_upstream=${svn_upstream%@*} - local n_stop="${#svn_remote[@]}" - for ((n=1; n <= n_stop; n++)); do - svn_upstream=${svn_upstream#${svn_remote[$n]}} - done - - if [[ -z "$svn_upstream" ]]; then - # default branch name for checkouts with no layout: - upstream=${GIT_SVN_ID:-git-svn} - else - upstream=${svn_upstream#/} - fi - elif [[ "svn+git" = "$upstream" ]]; then - upstream="@{upstream}" - fi - ;; - esac - - # Find how many commits we are ahead/behind our upstream - if [[ -z "$legacy" ]]; then - count="$(git rev-list --count --left-right \ - "$upstream"...HEAD 2>/dev/null)" - else - # produce equivalent output to --count for older versions of git - local commits - if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" - then - local commit behind=0 ahead=0 - for commit in $commits - do - case "$commit" in - "<"*) ((behind++)) ;; - *) ((ahead++)) ;; - esac - done - count="$behind $ahead" - else - count="" - fi - fi - - # calculate the result - if [[ -z "$verbose" ]]; then - case "$count" in - "") # no upstream - p="" ;; - "0 0") # equal to upstream - p="=" ;; - "0 "*) # ahead of upstream - p=">" ;; - *" 0") # behind upstream - p="<" ;; - *) # diverged from upstream - p="<>" ;; - esac - else - case "$count" in - "") # no upstream - p="" ;; - "0 0") # equal to upstream - p=" u=" ;; - "0 "*) # ahead of upstream - p=" u+${count#0 }" ;; - *" 0") # behind upstream - p=" u-${count% 0}" ;; - *) # diverged from upstream - p=" u+${count#* }-${count% *}" ;; - esac - fi - - } - - - # __git_ps1 accepts 0 or 1 arguments (i.e., format string) - # returns text to add to bash PS1 prompt (includes branch name) - __git_ps1 () - { - local g="$(__gitdir)" - if [ -n "$g" ]; then - local r="" - local b="" - if [ -f "$g/rebase-merge/interactive" ]; then - r="|REBASE-i" - b="$(cat "$g/rebase-merge/head-name")" - elif [ -d "$g/rebase-merge" ]; then - r="|REBASE-m" - b="$(cat "$g/rebase-merge/head-name")" - else - if [ -d "$g/rebase-apply" ]; then - if [ -f "$g/rebase-apply/rebasing" ]; then - r="|REBASE" - elif [ -f "$g/rebase-apply/applying" ]; then - r="|AM" - else - r="|AM/REBASE" - fi - elif [ -f "$g/MERGE_HEAD" ]; then - r="|MERGING" - elif [ -f "$g/CHERRY_PICK_HEAD" ]; then - r="|CHERRY-PICKING" - elif [ -f "$g/BISECT_LOG" ]; then - r="|BISECTING" - fi - - b="$(git symbolic-ref HEAD 2>/dev/null)" || { - - b="$( - case "${GIT_PS1_DESCRIBE_STYLE-}" in - (contains) - git describe --contains HEAD ;; - (branch) - git describe --contains --all HEAD ;; - (describe) - git describe HEAD ;; - (* | default) - git describe --tags --exact-match HEAD ;; - esac 2>/dev/null)" || - - b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || - b="unknown" - b="($b)" - } - fi - - local w="" - local i="" - local s="" - local u="" - local c="" - local p="" - - if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then - if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then - c="BARE:" - else - b="GIT_DIR!" - fi - elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then - if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then - if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then - git diff --no-ext-diff --quiet --exit-code || w="*" - if git rev-parse --quiet --verify HEAD >/dev/null; then - git diff-index --cached --quiet HEAD -- || i="+" - else - i="#" - fi - fi - fi - if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then - git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" - fi - - if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then - if [ -n "$(git ls-files --others --exclude-standard)" ]; then - u="%" - fi - fi - - if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then - __git_ps1_show_upstream - fi - fi - - local f="$w$i$s$u" - printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" - fi - } - __gitcomp_1 () { local c IFS=$' \t\n' @@@ -676,7 -428,9 +428,7 @@@ __git_complete_revlist_file ( *) pfx="$ref:$pfx" ;; esac - local IFS=$'\n' - COMPREPLY=($(compgen -P "$pfx" \ - -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \ + __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \ | sed '/^100... blob /{ s,^.* ,, s,$, , @@@ -690,7 -444,7 +442,7 @@@ s,$,/, } s/^.* //')" \ - -- "$cur_")) + "$pfx" "$cur_" "" ;; *...*) pfx="${cur_%...*}..." @@@ -846,8 -600,6 +598,8 @@@ __git_list_porcelain_commands ( checkout-index) : plumbing;; commit-tree) : plumbing;; count-objects) : infrequent;; + credential-cache) : credentials helper;; + credential-store) : credentials helper;; cvsexportcommit) : export;; cvsimport) : import;; cvsserver) : daemon;; @@@ -2599,7 -2351,7 +2351,7 @@@ _git_whatchanged ( _git_log } -_git () +__git_main () { local i c=1 command __git_dir @@@ -2650,7 -2402,7 +2402,7 @@@ fi } -_gitk () +__gitk_main () { __git_has_doubledash && return @@@ -2702,25 -2454,13 +2454,25 @@@ __git_complete ( || complete -o default -o nospace -F $wrapper $1 } -__git_complete git _git -__git_complete gitk _gitk +# wrapper for backwards compatibility +_git () +{ + __git_wrap__git_main +} + +# wrapper for backwards compatibility +_gitk () +{ + __git_wrap__gitk_main +} + +__git_complete git __git_main +__git_complete gitk __gitk_main # The following are necessary only for Cygwin, and only are needed # when the user has tab-completed the executable name and consequently # included the '.exe' suffix. # if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then -__git_complete git.exe _git +__git_complete git.exe __git_main fi diff --combined t/t9902-completion.sh index 256e6a0b3f,c8f3ec6bec..92d7eb47c2 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@@ -3,21 -3,9 +3,9 @@@ # Copyright (c) 2012 Felipe Contreras # - if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then - # we are in full-on bash mode - true - elif type bash >/dev/null 2>&1; then - # execute in full-on bash mode - unset POSIXLY_CORRECT - exec bash "$0" "$@" - else - echo '1..0 #SKIP skipping bash completion tests; bash not available' - exit 0 - fi - test_description='test bash completion' - . ./test-lib.sh + . ./lib-bash.sh complete () { @@@ -63,7 -51,7 +51,7 @@@ run_completion ( local _cword _words=( $1 ) (( _cword = ${#_words[@]} - 1 )) - __git_wrap_git && print_comp + __git_wrap__git_main && print_comp } test_completion ()