fix(githooks): pin absolute GIT_DIR and unset GIT_WORK_TREE in post-receive

This commit is contained in:
2026-06-16 16:31:35 +08:00
parent db350aae44
commit 436a0addcc
+9 -4
View File
@@ -7,17 +7,22 @@ export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
# git 调钩子时 cwd=GIT_DIR。此时 `git rev-parse --show-toplevel` 返回 # git 调钩子时 cwd=GIT_DIR 并设了 GIT_DIR=.(相对)。此时:
# `/.../repo/.git`(不报错,所以原版的 `|| echo $PWD` 退路不会触发), # 1. `git rev-parse --show-toplevel` 返回 `/.../repo/.git`(不报错),
# 会让 cd 误进 .git 目录。安全办法:拿绝对 git-dir 路径,取其父目录 # 会让原版 `|| echo $PWD` 退路不触发、cd 误进 .git
# 2. cd 到工作树后,GIT_DIR=. 不再指向 .git,下面 `git reset` 之类的
# 会报 `fatal: not a git repository: '.'`。
# 修正:拿绝对 git-dir,算出 worktree 根,并改用绝对 GIT_DIR。
GIT_DIR_ABS="$(git rev-parse --absolute-git-dir 2>/dev/null)" GIT_DIR_ABS="$(git rev-parse --absolute-git-dir 2>/dev/null)"
if [ -n "$GIT_DIR_ABS" ] && [ -d "$GIT_DIR_ABS" ]; then if [ -n "$GIT_DIR_ABS" ] && [ -d "$GIT_DIR_ABS" ]; then
REPO_TOPLEVEL="$(cd "$GIT_DIR_ABS/.." && pwd)" REPO_TOPLEVEL="$(cd "$GIT_DIR_ABS/.." && pwd)"
export GIT_DIR="$GIT_DIR_ABS"
else else
REPO_TOPLEVEL="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")" REPO_TOPLEVEL="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
fi fi
unset GIT_WORK_TREE
cd "$REPO_TOPLEVEL" || { echo "FATAL: cannot cd to $REPO_TOPLEVEL" >&2; exit 1; } cd "$REPO_TOPLEVEL" || { echo "FATAL: cannot cd to $REPO_TOPLEVEL" >&2; exit 1; }
echo "=== REPO_TOPLEVEL=$REPO_TOPLEVEL (GIT_DIR_ABS=$GIT_DIR_ABS) ===" >&2 echo "=== REPO_TOPLEVEL=$REPO_TOPLEVEL (GIT_DIR=$GIT_DIR) ===" >&2
# ============================================================ # ============================================================
# 0. sync_worktree —— 将工作树同步到新 push 的 HEAD # 0. sync_worktree —— 将工作树同步到新 push 的 HEAD