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). | #    1) Copy this file to somewhere (e.g. ~/.git-completion.sh). | ||||||
| #    2) Add the following line to your .bashrc/.zshrc: | #    2) Add the following line to your .bashrc/.zshrc: | ||||||
| #        source ~/.git-completion.sh | #        source ~/.git-completion.sh | ||||||
| # | #    3) Consider changing your PS1 to also show the current branch, | ||||||
| #    3) Consider changing your PS1 to also show the current branch: | #       see git-prompt.sh for details. | ||||||
| #         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. |  | ||||||
| # |  | ||||||
|  |  | ||||||
| if [[ -n ${ZSH_VERSION-} ]]; then | if [[ -n ${ZSH_VERSION-} ]]; then | ||||||
| 	autoload -U +X bashcompinit && bashcompinit | 	autoload -U +X bashcompinit && bashcompinit | ||||||
| @ -89,221 +51,6 @@ __gitdir () | |||||||
| 	fi | 	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 () | __gitcomp_1 () | ||||||
| { | { | ||||||
| 	local c IFS=$' \t\n' | 	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 | . ./lib-bash.sh | ||||||
|  |  | ||||||
| . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" | . "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh" | ||||||
|  |  | ||||||
| actual="$TRASH_DIRECTORY/actual" | actual="$TRASH_DIRECTORY/actual" | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user