add timeout to git operations
This commit is contained in:
@@ -356,6 +356,7 @@ The twelve available `PROMPT_COLOR_*` keys are:
|
|||||||
[prompt]
|
[prompt]
|
||||||
PROMPT_SHOW_GIT = 1
|
PROMPT_SHOW_GIT = 1
|
||||||
PROMPT_SHOW_GIT_STATUS = 1
|
PROMPT_SHOW_GIT_STATUS = 1
|
||||||
|
PROMPT_GIT_TIMEOUT = 2
|
||||||
PROMPT_SHOW_CONDA = 1
|
PROMPT_SHOW_CONDA = 1
|
||||||
PROMPT_SHOW_VENV = 1
|
PROMPT_SHOW_VENV = 1
|
||||||
PROMPT_SHOW_SESSION = 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 inside a Git repository
|
||||||
- `git:<branch>*` when local changes are present
|
- `git:<branch>*` when local changes are present
|
||||||
- `git:<branch> +N/-M` when ahead/behind upstream
|
- `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
|
- `conda:<env>` when a Conda environment is active
|
||||||
- `venv:<name>` when a Python virtualenv is active (and Conda is not)
|
- `venv:<name>` when a Python virtualenv is active (and Conda is not)
|
||||||
- `ssh`, `tmux`, `screen` markers when the session runs in those contexts
|
- `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:**
|
**Writing a custom theme file:**
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,10 @@ TERM=xterm-256color
|
|||||||
# Include Git dirty marker and upstream drift (+ahead/-behind) in the context.
|
# Include Git dirty marker and upstream drift (+ahead/-behind) in the context.
|
||||||
#PROMPT_SHOW_GIT_STATUS=1
|
#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.
|
# Show Conda environment name at the end of the top bar when active.
|
||||||
#PROMPT_SHOW_CONDA=1
|
#PROMPT_SHOW_CONDA=1
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -519,16 +519,42 @@ set_prompt()
|
|||||||
branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || \
|
branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null) || \
|
||||||
branch=$(git rev-parse --short HEAD 2>/dev/null) || return 0
|
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 [[ "${PROMPT_SHOW_GIT_STATUS:-1}" != "0" ]]; then
|
||||||
if ! git diff --no-ext-diff --quiet --ignore-submodules -- 2>/dev/null || \
|
local _ec
|
||||||
! git diff --cached --no-ext-diff --quiet --ignore-submodules -- 2>/dev/null; then
|
|
||||||
|
# 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="*"
|
dirty="*"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $timed_out -eq 0 ]]; then
|
||||||
local counts ahead behind
|
local counts ahead behind
|
||||||
counts=$(git rev-list --left-right --count "@{upstream}...HEAD" 2>/dev/null) || counts=""
|
counts=$("${_tw[@]}" git rev-list --left-right --count "@{upstream}...HEAD" 2>/dev/null)
|
||||||
if [[ "$counts" =~ ^([0-9]+)[[:space:]]+([0-9]+)$ ]]; then
|
_ec=$?
|
||||||
|
if [[ $_ec -eq 124 ]]; then
|
||||||
|
timed_out=1
|
||||||
|
elif [[ "$counts" =~ ^([0-9]+)[[:space:]]+([0-9]+)$ ]]; then
|
||||||
behind="${BASH_REMATCH[1]}"
|
behind="${BASH_REMATCH[1]}"
|
||||||
ahead="${BASH_REMATCH[2]}"
|
ahead="${BASH_REMATCH[2]}"
|
||||||
if [[ "$ahead" -gt 0 || "$behind" -gt 0 ]]; then
|
if [[ "$ahead" -gt 0 || "$behind" -gt 0 ]]; then
|
||||||
@@ -536,8 +562,13 @@ set_prompt()
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $timed_out -eq 1 ]]; then
|
||||||
|
printf "%s" "git:${branch}?"
|
||||||
|
else
|
||||||
printf "%s" "git:${branch}${dirty}${sync}"
|
printf "%s" "git:${branch}${dirty}${sync}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
local _prompt_conda_env
|
local _prompt_conda_env
|
||||||
|
|||||||
Reference in New Issue
Block a user