Skip to content

Commit 9501e92

Browse files
committed
ci: fix index.lock race in deploy prune step
The prune step piped 'git diff --name-only' into a while loop that ran 'git checkout' per file. The streaming diff refreshes the index and holds .git/index.lock while the loop's checkout tries to write it, racing and failing with 'Unable to create index.lock: File exists' (exit 128). Materialise each file list fully before any checkout, set GIT_OPTIONAL_LOCKS=0 so read-only diffs never take the lock, and batch the reverts into a single xargs git checkout call. Assisted-by: ClaudeCode:claude-opus-4-8 Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
1 parent d2ba51b commit 9501e92

1 file changed

Lines changed: 27 additions & 9 deletions

File tree

.github/workflows/deploy-docs.yml

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,27 +189,45 @@ jobs:
189189
# ----------------------------------------------------------------
190190
NOISE='lastupdated|Last updated on|data-zoom-id'
191191
192-
# 1) Revert HTML files whose only changes are noise.
193-
git diff --name-only HEAD -- '*.html' | while IFS= read -r f; do
192+
# Read-only diffs must not take .git/index.lock: a `git diff` that
193+
# refreshes the index while a `git checkout` writes it races on the
194+
# lock. GIT_OPTIONAL_LOCKS=0 suppresses the refresh write; we also
195+
# materialise each file list fully before running any checkout, and
196+
# batch the reverts into a single checkout call.
197+
export GIT_OPTIONAL_LOCKS=0
198+
199+
# 1) Collect HTML files whose only changes are noise, then revert them.
200+
: > /tmp/revert-html.txt
201+
git diff --name-only HEAD -- '*.html' > /tmp/changed-html.txt
202+
while IFS= read -r f; do
194203
[ -n "$f" ] || continue
195204
real=$(git diff HEAD -- "$f" | grep -E '^[+-]' | grep -vE '^[+-]{3}' | grep -ivE "$NOISE" | wc -l)
196-
[ "$real" -eq 0 ] && git checkout HEAD -- "$f"
197-
done
205+
[ "$real" -eq 0 ] && printf '%s\n' "$f" >> /tmp/revert-html.txt
206+
done < /tmp/changed-html.txt
207+
if [ -s /tmp/revert-html.txt ]; then
208+
xargs -a /tmp/revert-html.txt -r git checkout HEAD --
209+
fi
198210
199211
# 2) PDF/ePub binaries regenerate every build with no content change.
200212
# Keep them only for a version folder that still has a real HTML
201-
# change after step 1; otherwise revert them too.
202-
git diff --name-only HEAD -- '*.pdf' '*.epub' | while IFS= read -r f; do
213+
# change after step 1; otherwise revert them too. Runs after the
214+
# HTML revert so the per-folder check sees the pruned tree.
215+
: > /tmp/revert-bin.txt
216+
git diff --name-only HEAD -- '*.pdf' '*.epub' > /tmp/changed-bin.txt
217+
while IFS= read -r f; do
203218
[ -n "$f" ] || continue
204219
case "$f" in
205220
server/*)
206221
vdir="server/$(printf '%s' "${f#server/}" | cut -d/ -f1)"
207222
remaining=$(git diff --name-only HEAD -- "$vdir" | grep -vE '\.(epub|pdf)$' | wc -l)
208-
[ "$remaining" -eq 0 ] && git checkout HEAD -- "$f"
223+
[ "$remaining" -eq 0 ] && printf '%s\n' "$f" >> /tmp/revert-bin.txt
209224
;;
210-
*) git checkout HEAD -- "$f" ;;
225+
*) printf '%s\n' "$f" >> /tmp/revert-bin.txt ;;
211226
esac
212-
done
227+
done < /tmp/changed-bin.txt
228+
if [ -s /tmp/revert-bin.txt ]; then
229+
xargs -a /tmp/revert-bin.txt -r git checkout HEAD --
230+
fi
213231
214232
# Anything real left to deploy? (tracked diffs or brand-new files)
215233
if [ -n "$(git status --porcelain)" ]; then

0 commit comments

Comments
 (0)