2dedb9573c
Apple Git osxkeychain exclusive-locks argv[0]. A relative name looks in cwd and fails with "failed to lock git-credential-osxkeychain".
61 lines
1.8 KiB
Bash
Executable File
61 lines
1.8 KiB
Bash
Executable File
#!/bin/bash
|
||
# 跨平台 Git 凭据 helper(不依赖 includeIf ondarwin/onlinux,兼容 Git < 2.36)
|
||
# macOS: osxkeychain → store
|
||
# Linux: libsecret → store
|
||
set -euo pipefail
|
||
|
||
warn_store_fallback() {
|
||
local reason="$1"
|
||
local marker="${XDG_CACHE_HOME:-$HOME/.cache}/git-credential-store.warned"
|
||
[[ -f "$marker" ]] && return 0
|
||
mkdir -p "$(dirname "$marker")"
|
||
touch "$marker"
|
||
cat >&2 <<EOF
|
||
提示: Git 凭据使用 store 明文保存到 ~/.git-credentials(${reason})。
|
||
|
||
建议:
|
||
macOS: 通常可用 osxkeychain(Keychain)
|
||
Linux: sudo apt install libsecret-1-0 git-credential-libsecret
|
||
|
||
请确保 ~/.git-credentials 权限为 600。
|
||
EOF
|
||
}
|
||
|
||
# helper 在 `git --exec-path`,不一定在 PATH。必须 exec 绝对路径:
|
||
# Apple Git 的 osxkeychain 会对 argv[0] 做 O_EXLOCK,相对名会去锁 cwd 下的同名文件。
|
||
dotfile_git_credential_exec() {
|
||
local name="$1"
|
||
shift
|
||
local helper=""
|
||
local exec_path
|
||
exec_path="$(git --exec-path 2>/dev/null || true)"
|
||
if [ -n "$exec_path" ] && [ -x "$exec_path/git-credential-$name" ]; then
|
||
helper="$exec_path/git-credential-$name"
|
||
elif command -v "git-credential-$name" >/dev/null 2>&1; then
|
||
helper="$(command -v "git-credential-$name")"
|
||
else
|
||
return 1
|
||
fi
|
||
exec "$helper" "$@"
|
||
}
|
||
|
||
case "$(uname -s)" in
|
||
Darwin)
|
||
dotfile_git_credential_exec osxkeychain "$@" || true
|
||
warn_store_fallback "未找到 osxkeychain"
|
||
dotfile_git_credential_exec store "$@" || true
|
||
;;
|
||
Linux)
|
||
dotfile_git_credential_exec libsecret "$@" || true
|
||
warn_store_fallback "未找到 git-credential-libsecret"
|
||
dotfile_git_credential_exec store "$@" || true
|
||
;;
|
||
*)
|
||
warn_store_fallback "未知系统 $(uname -s)"
|
||
dotfile_git_credential_exec store "$@" || true
|
||
;;
|
||
esac
|
||
|
||
echo "git credential helper 不可用" >&2
|
||
exit 1
|