Add following to your .bashrc:
__git_ps1() { setsid -w /bin/bash -c 'sleep 1 & . /usr/lib/git-core/git-sh-prompt && __git_ps1 "$@" & wait -n; p=$(/usr/bin/ps --no-headers -opgrp $$) && [ $$ = ${p:-x} ] && /usr/bin/kill -9 0; echo "PGRP mismatch $$ $p" >&2' bash "$@"; }1s usually is enough for local files which are in cache on modern machines, but does not delays the shell prompt too much in case network share need a bit longer.
Note: Due to timeout killing git this may leave .lock-files in your .git directory, which is a bit annoying, as git bails out if it sees such .lock when altering a .git repo. However git tells the lockfile positions and you then can(must) manually rm them. You can improve this by setting GIT_PS1_xxxx variables such, that git needs no locking when evaluating the $PS1. However I am not completely sure which options causes this issue or not. YMMV.
What it does:
setsid -w /bin/bash -c 'SCRIPT' bash "$@"runsSCRIPTin a new process groupsleep 1 &sets the timeout. /usr/lib/git-core/git-sh-prompt && __git_ps1 "$@" &runs the git prompt in parallel/usr/lib/git-core/git-sh-promptis for Ubuntu 22.04, change it if needed
wait -n;waits for either thesleepor__git_ps1to return- The first one wins
p=$(/usr/bin/ps --no-headers -opgrp $$) && [ $$ = ${p:-x} ] &&is just a safeguard to checksetsidworked and we are really a process group leader$$works here correctly, as we are within single quotes
kill -9 0unconditionally kills the entire process group- all
gitthat may still execute - including the
/bin/bash
- all
echo "PGRP mismatch $$ $p" >&2'is never reached- This informs you that either
setsidis a fake - or something else (
kill?) did not work as expected
- This informs you that either
The safeguard protects against the case that setsid does not work as advertised. Without your current shell might get killed, which would make it impossible to spawn an interactive shell.
Updated my SO answer to include this, too:
FTR before it looked like