completion: split __git_ps1 into a separate script
bash-completion 1.90 shipped with support to load completions dynamically[1], which means the git completion script wouldn't be loaded until the user types 'git <tab>'--this creates a problem to people using __git_ps1(); that function won't be available when the shell is first created. For now distributions have workarounded this issue by moving the git completion to the "compatdir"[2]; this of course is not ideal. The solution, proposed by Kerrick Staley[3], is to split the git script in two; the part that deals with __git_ps1() in one (i.e. git-prompt.sh), and everything else in another (i.e. git-completion.bash). Another benefit of this is that zsh user that are not interested in the bash completion can use it for their prompts, which has been tried before[4]. The only slight issue is that __gitdir() would be duplicated, but this is probably not a big deal. So let's go ahead and move __git_ps1() to a new file. While at this, I took the liberty to reformat the help text in the new file. [1] http://anonscm.debian.org/gitweb/?p=bash-completion/bash-completion.git;a=commitdiff;h=99c4f7f25f50a7cb2fce86055bddfe389effa559 [2] http://projects.archlinux.org/svntogit/packages.git/commit/trunk?h=packages/git&id=974380fabb8f9f412990b17063bf578d98c44a82 [3] http://mid.gmane.org/CANaWP3w9KDu57aHquRRYt8td_haSWTBKs7zUHy-xu0B61gmr9A@mail.gmail.com [4] http://mid.gmane.org/1303824288-15591-1-git-send-email-mstormo@gmail.com Cc: Kerrick Staley <mail@kerrickstaley.com> Cc: Marius Storm-Olsen <mstormo@gmail.com> Cc: Ville Skyttä <ville.skytta@iki.fi> Cc: Dan McGee <dan@archlinux.org> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
		 Felipe Contreras
					Felipe Contreras
				
			
				
					committed by
					
						 Junio C Hamano
						Junio C Hamano
					
				
			
			
				
	
			
			
			 Junio C Hamano
						Junio C Hamano
					
				
			
						parent
						
							1098ff5a21
						
					
				
				
					commit
					af31a456b4
				
			| @ -20,46 +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 | ||||
| @ -89,221 +51,6 @@ __gitdir () | ||||
| 	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' | ||||
|  | ||||
							
								
								
									
										287
									
								
								contrib/completion/git-prompt.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								contrib/completion/git-prompt.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,287 @@ | ||||
| # bash/zsh git prompt support | ||||
| # | ||||
| # Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org> | ||||
| # Distributed under the GNU General Public License, version 2.0. | ||||
| # | ||||
| # This script allows you to see the current branch in your prompt. | ||||
| # | ||||
| # To enable: | ||||
| # | ||||
| #    1) Copy this file to somewhere (e.g. ~/.git-prompt.sh). | ||||
| #    2) Add the following line to your .bashrc/.zshrc: | ||||
| #        source ~/.git-prompt.sh | ||||
| #    3) Change 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. | ||||
|  | ||||
| # __gitdir accepts 0 or 1 arguments (i.e., location) | ||||
| # returns location of .git repo | ||||
| __gitdir () | ||||
| { | ||||
| 	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 | ||||
| 			git rev-parse --git-dir 2>/dev/null | ||||
| 		fi | ||||
| 	elif [ -d "$1/.git" ]; then | ||||
| 		echo "$1/.git" | ||||
| 	else | ||||
| 		echo "$1" | ||||
| 	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 | ||||
| } | ||||
| @ -7,7 +7,7 @@ test_description='test git-specific bash prompt functions' | ||||
|  | ||||
| . ./lib-bash.sh | ||||
|  | ||||
| . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" | ||||
| . "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh" | ||||
|  | ||||
| actual="$TRASH_DIRECTORY/actual" | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user