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 "$@"
runsSCRIPT
in 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-prompt
is for Ubuntu 22.04, change it if needed
wait -n;
waits for either thesleep
or__git_ps1
to return- The first one wins
p=$(/usr/bin/ps --no-headers -opgrp $$) && [ $$ = ${p:-x} ] &&
is just a safeguard to checksetsid
worked and we are really a process group leader$$
works here correctly, as we are within single quotes
kill -9 0
unconditionally kills the entire process group- all
git
that may still execute - including the
/bin/bash
- all
echo "PGRP mismatch $$ $p" >&2'
is never reached- This informs you that either
setsid
is 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