mirror of
				https://github.com/ohmyzsh/ohmyzsh.git
				synced 2025-11-04 13:21:19 +08:00 
			
		
		
		
	fix(async): ensure git_prompt_status can be registered (#13134)
				
					
				
			This commit is contained in:
		
							parent
							
								
									d39804a5a6
								
							
						
					
					
						commit
						13c702964c
					
				
							
								
								
									
										198
									
								
								lib/git.zsh
									
									
									
									
									
								
							
							
						
						
									
										198
									
								
								lib/git.zsh
									
									
									
									
									
								
							@ -39,6 +39,105 @@ function _omz_git_prompt_info() {
 | 
			
		||||
  echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _omz_git_prompt_status() {
 | 
			
		||||
  [[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
 | 
			
		||||
 | 
			
		||||
  # Maps a git status prefix to an internal constant
 | 
			
		||||
  # This cannot use the prompt constants, as they may be empty
 | 
			
		||||
  local -A prefix_constant_map
 | 
			
		||||
  prefix_constant_map=(
 | 
			
		||||
    '\?\? '     'UNTRACKED'
 | 
			
		||||
    'A  '       'ADDED'
 | 
			
		||||
    'M  '       'MODIFIED'
 | 
			
		||||
    'MM '       'MODIFIED'
 | 
			
		||||
    ' M '       'MODIFIED'
 | 
			
		||||
    'AM '       'MODIFIED'
 | 
			
		||||
    ' T '       'MODIFIED'
 | 
			
		||||
    'R  '       'RENAMED'
 | 
			
		||||
    ' D '       'DELETED'
 | 
			
		||||
    'D  '       'DELETED'
 | 
			
		||||
    'UU '       'UNMERGED'
 | 
			
		||||
    'ahead'     'AHEAD'
 | 
			
		||||
    'behind'    'BEHIND'
 | 
			
		||||
    'diverged'  'DIVERGED'
 | 
			
		||||
    'stashed'   'STASHED'
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  # Maps the internal constant to the prompt theme
 | 
			
		||||
  local -A constant_prompt_map
 | 
			
		||||
  constant_prompt_map=(
 | 
			
		||||
    'UNTRACKED' "$ZSH_THEME_GIT_PROMPT_UNTRACKED"
 | 
			
		||||
    'ADDED'     "$ZSH_THEME_GIT_PROMPT_ADDED"
 | 
			
		||||
    'MODIFIED'  "$ZSH_THEME_GIT_PROMPT_MODIFIED"
 | 
			
		||||
    'RENAMED'   "$ZSH_THEME_GIT_PROMPT_RENAMED"
 | 
			
		||||
    'DELETED'   "$ZSH_THEME_GIT_PROMPT_DELETED"
 | 
			
		||||
    'UNMERGED'  "$ZSH_THEME_GIT_PROMPT_UNMERGED"
 | 
			
		||||
    'AHEAD'     "$ZSH_THEME_GIT_PROMPT_AHEAD"
 | 
			
		||||
    'BEHIND'    "$ZSH_THEME_GIT_PROMPT_BEHIND"
 | 
			
		||||
    'DIVERGED'  "$ZSH_THEME_GIT_PROMPT_DIVERGED"
 | 
			
		||||
    'STASHED'   "$ZSH_THEME_GIT_PROMPT_STASHED"
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  # The order that the prompt displays should be added to the prompt
 | 
			
		||||
  local status_constants
 | 
			
		||||
  status_constants=(
 | 
			
		||||
    UNTRACKED ADDED MODIFIED RENAMED DELETED
 | 
			
		||||
    STASHED UNMERGED AHEAD BEHIND DIVERGED
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  local status_text
 | 
			
		||||
  status_text="$(__git_prompt_git status --porcelain -b 2> /dev/null)"
 | 
			
		||||
 | 
			
		||||
  # Don't continue on a catastrophic failure
 | 
			
		||||
  if [[ $? -eq 128 ]]; then
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # A lookup table of each git status encountered
 | 
			
		||||
  local -A statuses_seen
 | 
			
		||||
 | 
			
		||||
  if __git_prompt_git rev-parse --verify refs/stash &>/dev/null; then
 | 
			
		||||
    statuses_seen[STASHED]=1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  local status_lines
 | 
			
		||||
  status_lines=("${(@f)${status_text}}")
 | 
			
		||||
 | 
			
		||||
  # If the tracking line exists, get and parse it
 | 
			
		||||
  if [[ "$status_lines[1]" =~ "^## [^ ]+ \[(.*)\]" ]]; then
 | 
			
		||||
    local branch_statuses
 | 
			
		||||
    branch_statuses=("${(@s/,/)match}")
 | 
			
		||||
    for branch_status in $branch_statuses; do
 | 
			
		||||
      if [[ ! $branch_status =~ "(behind|diverged|ahead) ([0-9]+)?" ]]; then
 | 
			
		||||
        continue
 | 
			
		||||
      fi
 | 
			
		||||
      local last_parsed_status=$prefix_constant_map[$match[1]]
 | 
			
		||||
      statuses_seen[$last_parsed_status]=$match[2]
 | 
			
		||||
    done
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # For each status prefix, do a regex comparison
 | 
			
		||||
  for status_prefix in ${(k)prefix_constant_map}; do
 | 
			
		||||
    local status_constant="${prefix_constant_map[$status_prefix]}"
 | 
			
		||||
    local status_regex=$'(^|\n)'"$status_prefix"
 | 
			
		||||
 | 
			
		||||
    if [[ "$status_text" =~ $status_regex ]]; then
 | 
			
		||||
      statuses_seen[$status_constant]=1
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  # Display the seen statuses in the order specified
 | 
			
		||||
  local status_prompt
 | 
			
		||||
  for status_constant in $status_constants; do
 | 
			
		||||
    if (( ${+statuses_seen[$status_constant]} )); then
 | 
			
		||||
      local next_display=$constant_prompt_map[$status_constant]
 | 
			
		||||
      status_prompt="$next_display$status_prompt"
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  echo $status_prompt
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Use async version if setting is enabled, or unset but zsh version is at least 5.0.6.
 | 
			
		||||
# This avoids async prompt issues caused by previous zsh versions:
 | 
			
		||||
# - https://github.com/ohmyzsh/ohmyzsh/issues/12331
 | 
			
		||||
@ -246,105 +345,6 @@ function git_prompt_long_sha() {
 | 
			
		||||
  SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _omz_git_prompt_status() {
 | 
			
		||||
  [[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
 | 
			
		||||
 | 
			
		||||
  # Maps a git status prefix to an internal constant
 | 
			
		||||
  # This cannot use the prompt constants, as they may be empty
 | 
			
		||||
  local -A prefix_constant_map
 | 
			
		||||
  prefix_constant_map=(
 | 
			
		||||
    '\?\? '     'UNTRACKED'
 | 
			
		||||
    'A  '       'ADDED'
 | 
			
		||||
    'M  '       'MODIFIED'
 | 
			
		||||
    'MM '       'MODIFIED'
 | 
			
		||||
    ' M '       'MODIFIED'
 | 
			
		||||
    'AM '       'MODIFIED'
 | 
			
		||||
    ' T '       'MODIFIED'
 | 
			
		||||
    'R  '       'RENAMED'
 | 
			
		||||
    ' D '       'DELETED'
 | 
			
		||||
    'D  '       'DELETED'
 | 
			
		||||
    'UU '       'UNMERGED'
 | 
			
		||||
    'ahead'     'AHEAD'
 | 
			
		||||
    'behind'    'BEHIND'
 | 
			
		||||
    'diverged'  'DIVERGED'
 | 
			
		||||
    'stashed'   'STASHED'
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  # Maps the internal constant to the prompt theme
 | 
			
		||||
  local -A constant_prompt_map
 | 
			
		||||
  constant_prompt_map=(
 | 
			
		||||
    'UNTRACKED' "$ZSH_THEME_GIT_PROMPT_UNTRACKED"
 | 
			
		||||
    'ADDED'     "$ZSH_THEME_GIT_PROMPT_ADDED"
 | 
			
		||||
    'MODIFIED'  "$ZSH_THEME_GIT_PROMPT_MODIFIED"
 | 
			
		||||
    'RENAMED'   "$ZSH_THEME_GIT_PROMPT_RENAMED"
 | 
			
		||||
    'DELETED'   "$ZSH_THEME_GIT_PROMPT_DELETED"
 | 
			
		||||
    'UNMERGED'  "$ZSH_THEME_GIT_PROMPT_UNMERGED"
 | 
			
		||||
    'AHEAD'     "$ZSH_THEME_GIT_PROMPT_AHEAD"
 | 
			
		||||
    'BEHIND'    "$ZSH_THEME_GIT_PROMPT_BEHIND"
 | 
			
		||||
    'DIVERGED'  "$ZSH_THEME_GIT_PROMPT_DIVERGED"
 | 
			
		||||
    'STASHED'   "$ZSH_THEME_GIT_PROMPT_STASHED"
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  # The order that the prompt displays should be added to the prompt
 | 
			
		||||
  local status_constants
 | 
			
		||||
  status_constants=(
 | 
			
		||||
    UNTRACKED ADDED MODIFIED RENAMED DELETED
 | 
			
		||||
    STASHED UNMERGED AHEAD BEHIND DIVERGED
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  local status_text
 | 
			
		||||
  status_text="$(__git_prompt_git status --porcelain -b 2> /dev/null)"
 | 
			
		||||
 | 
			
		||||
  # Don't continue on a catastrophic failure
 | 
			
		||||
  if [[ $? -eq 128 ]]; then
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # A lookup table of each git status encountered
 | 
			
		||||
  local -A statuses_seen
 | 
			
		||||
 | 
			
		||||
  if __git_prompt_git rev-parse --verify refs/stash &>/dev/null; then
 | 
			
		||||
    statuses_seen[STASHED]=1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  local status_lines
 | 
			
		||||
  status_lines=("${(@f)${status_text}}")
 | 
			
		||||
 | 
			
		||||
  # If the tracking line exists, get and parse it
 | 
			
		||||
  if [[ "$status_lines[1]" =~ "^## [^ ]+ \[(.*)\]" ]]; then
 | 
			
		||||
    local branch_statuses
 | 
			
		||||
    branch_statuses=("${(@s/,/)match}")
 | 
			
		||||
    for branch_status in $branch_statuses; do
 | 
			
		||||
      if [[ ! $branch_status =~ "(behind|diverged|ahead) ([0-9]+)?" ]]; then
 | 
			
		||||
        continue
 | 
			
		||||
      fi
 | 
			
		||||
      local last_parsed_status=$prefix_constant_map[$match[1]]
 | 
			
		||||
      statuses_seen[$last_parsed_status]=$match[2]
 | 
			
		||||
    done
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # For each status prefix, do a regex comparison
 | 
			
		||||
  for status_prefix in ${(k)prefix_constant_map}; do
 | 
			
		||||
    local status_constant="${prefix_constant_map[$status_prefix]}"
 | 
			
		||||
    local status_regex=$'(^|\n)'"$status_prefix"
 | 
			
		||||
 | 
			
		||||
    if [[ "$status_text" =~ $status_regex ]]; then
 | 
			
		||||
      statuses_seen[$status_constant]=1
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  # Display the seen statuses in the order specified
 | 
			
		||||
  local status_prompt
 | 
			
		||||
  for status_constant in $status_constants; do
 | 
			
		||||
    if (( ${+statuses_seen[$status_constant]} )); then
 | 
			
		||||
      local next_display=$constant_prompt_map[$status_constant]
 | 
			
		||||
      status_prompt="$next_display$status_prompt"
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
 | 
			
		||||
  echo $status_prompt
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Outputs the name of the current user
 | 
			
		||||
# Usage example: $(git_current_user_name)
 | 
			
		||||
function git_current_user_name() {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user