[ZSH] Bound background git calls to prevent zombie leaks
The check_tools_repo (git ls-remote | awk) and update_dotfiles (git fetch) background jobs could stall on a network call and, being disowned (&!), orphan into days-long processes holding unreaped git/awk children. Bound both network probes with `timeout` (guarded, absent on macOS) and disable ssh multiplexing so no daemonized mux master inherits our fds. Also dedup the double update_dotfiles startup call. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
committed by
Fabian Ising
co-authored by
Claude Opus 4.8
parent
57a0089b3a
commit
7d5d4be328
+12
-2
@@ -12,7 +12,13 @@
|
|||||||
# Per-branch, so `server` on each device fast-forwards to origin/server.
|
# Per-branch, so `server` on each device fast-forwards to origin/server.
|
||||||
update_dotfiles() {
|
update_dotfiles() {
|
||||||
local repo="$HOME/dotfiles"
|
local repo="$HOME/dotfiles"
|
||||||
git -C "$repo" fetch --quiet 2>/dev/null || return
|
# Bound the network call so a stalled fetch can't wedge this backgrounded
|
||||||
|
# (&!) job into a days-long orphan holding unreaped children. `timeout` is
|
||||||
|
# absent on macOS, so only use it when present. Disable ssh multiplexing so
|
||||||
|
# no daemonized mux master can inherit and keep our fds open past git's exit.
|
||||||
|
local -a TO; (( $+commands[timeout] )) && TO=(timeout -k 5 15)
|
||||||
|
GIT_SSH_COMMAND='ssh -o BatchMode=yes -o ConnectTimeout=5 -o ControlMaster=no -o ControlPath=none' \
|
||||||
|
$TO git -C "$repo" fetch --quiet </dev/null 2>/dev/null || return
|
||||||
git -C "$repo" rev-parse --abbrev-ref '@{u}' >/dev/null 2>&1 || return # no upstream
|
git -C "$repo" rev-parse --abbrev-ref '@{u}' >/dev/null 2>&1 || return # no upstream
|
||||||
git -C "$repo" merge-base --is-ancestor '@{u}' HEAD 2>/dev/null && return # already current
|
git -C "$repo" merge-base --is-ancestor '@{u}' HEAD 2>/dev/null && return # already current
|
||||||
git -C "$repo" merge --ff-only --quiet '@{u}' 2>/dev/null \
|
git -C "$repo" merge --ff-only --quiet '@{u}' 2>/dev/null \
|
||||||
@@ -31,13 +37,17 @@ update_dotfiles &!
|
|||||||
# Uses the first candidate that is a git checkout; covers global and per-user layouts.
|
# Uses the first candidate that is a git checkout; covers global and per-user layouts.
|
||||||
check_tools_repo() {
|
check_tools_repo() {
|
||||||
local repo branch remote mergeref remote_sha local_sha cmd
|
local repo branch remote mergeref remote_sha local_sha cmd
|
||||||
|
# See update_dotfiles: bound the network probe (timeout, absent on macOS) and
|
||||||
|
# disable ssh multiplexing so a stalled ls-remote can't orphan this &! job.
|
||||||
|
local -a TO; (( $+commands[timeout] )) && TO=(timeout -k 5 10)
|
||||||
for repo in /opt/tools "$HOME/tools" "$HOME/tools/tools-repo"; do
|
for repo in /opt/tools "$HOME/tools" "$HOME/tools/tools-repo"; do
|
||||||
local -a g=(git -c 'safe.directory=*' -C "$repo")
|
local -a g=(git -c 'safe.directory=*' -C "$repo")
|
||||||
$g rev-parse --is-inside-work-tree >/dev/null 2>&1 || continue
|
$g rev-parse --is-inside-work-tree >/dev/null 2>&1 || continue
|
||||||
branch=$($g symbolic-ref --short HEAD 2>/dev/null) || return
|
branch=$($g symbolic-ref --short HEAD 2>/dev/null) || return
|
||||||
remote=$($g config "branch.$branch.remote" 2>/dev/null) || return # no upstream
|
remote=$($g config "branch.$branch.remote" 2>/dev/null) || return # no upstream
|
||||||
mergeref=$($g config "branch.$branch.merge" 2>/dev/null) || return
|
mergeref=$($g config "branch.$branch.merge" 2>/dev/null) || return
|
||||||
remote_sha=$($g ls-remote "$remote" "$mergeref" 2>/dev/null | awk '{print $1}')
|
remote_sha=$(GIT_SSH_COMMAND='ssh -o BatchMode=yes -o ConnectTimeout=5 -o ControlMaster=no -o ControlPath=none' \
|
||||||
|
$TO $g ls-remote "$remote" "$mergeref" </dev/null 2>/dev/null | awk '{print $1}')
|
||||||
local_sha=$($g rev-parse HEAD 2>/dev/null)
|
local_sha=$($g rev-parse HEAD 2>/dev/null)
|
||||||
[[ -n "$remote_sha" && -n "$local_sha" ]] || return # remote unreachable
|
[[ -n "$remote_sha" && -n "$local_sha" ]] || return # remote unreachable
|
||||||
[[ "$remote_sha" == "$local_sha" ]] && return # already current
|
[[ "$remote_sha" == "$local_sha" ]] && return # already current
|
||||||
|
|||||||
Reference in New Issue
Block a user