add timeout to git operations
This commit is contained in:
@@ -356,6 +356,7 @@ The twelve available `PROMPT_COLOR_*` keys are:
|
||||
[prompt]
|
||||
PROMPT_SHOW_GIT = 1
|
||||
PROMPT_SHOW_GIT_STATUS = 1
|
||||
PROMPT_GIT_TIMEOUT = 2
|
||||
PROMPT_SHOW_CONDA = 1
|
||||
PROMPT_SHOW_VENV = 1
|
||||
PROMPT_SHOW_SESSION = 1
|
||||
@@ -366,10 +367,11 @@ When enabled, the top prompt bar appends:
|
||||
- `git:<branch>` when inside a Git repository
|
||||
- `git:<branch>*` when local changes are present
|
||||
- `git:<branch> +N/-M` when ahead/behind upstream
|
||||
- `git:<branch>?` when `git diff` or `git rev-list` exceeded `PROMPT_GIT_TIMEOUT`
|
||||
- `conda:<env>` when a Conda environment is active
|
||||
- `venv:<name>` when a Python virtualenv is active (and Conda is not)
|
||||
- `ssh`, `tmux`, `screen` markers when the session runs in those contexts
|
||||
- both, separated by `|`, when both are available
|
||||
- all, separated by `|`, when several are available
|
||||
|
||||
**Writing a custom theme file:**
|
||||
|
||||
|
||||
@@ -201,6 +201,10 @@ TERM=xterm-256color
|
||||
# Include Git dirty marker and upstream drift (+ahead/-behind) in the context.
|
||||
#PROMPT_SHOW_GIT_STATUS=1
|
||||
#
|
||||
# Timeout in seconds for git diff and git rev-list operations.
|
||||
# If exceeded, the prompt displays git:<branch>? instead of full status.
|
||||
#PROMPT_GIT_TIMEOUT=2
|
||||
#
|
||||
# Show Conda environment name at the end of the top bar when active.
|
||||
#PROMPT_SHOW_CONDA=1
|
||||
#
|
||||
|
||||
@@ -121,7 +121,7 @@ load_theme()
|
||||
_lth_line="${_lth_line%$'\r'}" # strip CR
|
||||
_lth_line="${_lth_line#"${_lth_line%%[![:space:]]*}"}" # ltrim
|
||||
_lth_line="${_lth_line%"${_lth_line##*[![:space:]]}"}" # rtrim
|
||||
[[ -z "$_lth_line" || "$_lth_line" == '#'* ]] && continue # blank/comment
|
||||
[[ -z "$_lth_line" || "$_lth_line" == '#'* ]] && continue # blank/comment
|
||||
[[ "$_lth_line" == 'export '* ]] && _lth_line="${_lth_line#export }" # strip prefix
|
||||
|
||||
if [[ "$_lth_line" != *=* ]]; then
|
||||
@@ -519,25 +519,56 @@ set_prompt()
|
||||
branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || \
|
||||
branch=$(git rev-parse --short HEAD 2>/dev/null) || return 0
|
||||
|
||||
local dirty="" sync=""
|
||||
local dirty="" sync="" timed_out=0
|
||||
local _git_timeout="${PROMPT_GIT_TIMEOUT:-2}"
|
||||
|
||||
# Build a timeout wrapper if the 'timeout' command is available;
|
||||
# fall back to direct execution on systems that lack it.
|
||||
local -a _tw=()
|
||||
command -v timeout >/dev/null 2>&1 && _tw=(timeout "$_git_timeout")
|
||||
|
||||
if [[ "${PROMPT_SHOW_GIT_STATUS:-1}" != "0" ]]; then
|
||||
if ! git diff --no-ext-diff --quiet --ignore-submodules -- 2>/dev/null || \
|
||||
! git diff --cached --no-ext-diff --quiet --ignore-submodules -- 2>/dev/null; then
|
||||
local _ec
|
||||
|
||||
# Dirty check — working tree
|
||||
"${_tw[@]}" git diff --no-ext-diff --quiet --ignore-submodules -- 2>/dev/null
|
||||
_ec=$?
|
||||
if [[ $_ec -eq 124 ]]; then
|
||||
timed_out=1
|
||||
elif [[ $_ec -ne 0 ]]; then
|
||||
dirty="*"
|
||||
else
|
||||
# Dirty check — index
|
||||
"${_tw[@]}" git diff --cached --no-ext-diff --quiet --ignore-submodules -- 2>/dev/null
|
||||
_ec=$?
|
||||
if [[ $_ec -eq 124 ]]; then
|
||||
timed_out=1
|
||||
elif [[ $_ec -ne 0 ]]; then
|
||||
dirty="*"
|
||||
fi
|
||||
fi
|
||||
|
||||
local counts ahead behind
|
||||
counts=$(git rev-list --left-right --count "@{upstream}...HEAD" 2>/dev/null) || counts=""
|
||||
if [[ "$counts" =~ ^([0-9]+)[[:space:]]+([0-9]+)$ ]]; then
|
||||
behind="${BASH_REMATCH[1]}"
|
||||
ahead="${BASH_REMATCH[2]}"
|
||||
if [[ "$ahead" -gt 0 || "$behind" -gt 0 ]]; then
|
||||
sync=" +${ahead}/-${behind}"
|
||||
if [[ $timed_out -eq 0 ]]; then
|
||||
local counts ahead behind
|
||||
counts=$("${_tw[@]}" git rev-list --left-right --count "@{upstream}...HEAD" 2>/dev/null)
|
||||
_ec=$?
|
||||
if [[ $_ec -eq 124 ]]; then
|
||||
timed_out=1
|
||||
elif [[ "$counts" =~ ^([0-9]+)[[:space:]]+([0-9]+)$ ]]; then
|
||||
behind="${BASH_REMATCH[1]}"
|
||||
ahead="${BASH_REMATCH[2]}"
|
||||
if [[ "$ahead" -gt 0 || "$behind" -gt 0 ]]; then
|
||||
sync=" +${ahead}/-${behind}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "%s" "git:${branch}${dirty}${sync}"
|
||||
if [[ $timed_out -eq 1 ]]; then
|
||||
printf "%s" "git:${branch}?"
|
||||
else
|
||||
printf "%s" "git:${branch}${dirty}${sync}"
|
||||
fi
|
||||
}
|
||||
|
||||
local _prompt_conda_env
|
||||
|
||||
Reference in New Issue
Block a user