エラーメッセージ
error: gpg failed to sign the data
別の表記
- fatal: failed to write commit object
- gpg: skipped "ABCDEF0123456789": No secret key
- gpg: signing failed: No secret key
Git は最初の行の後に gpg の stderr を出力します。たとえば「gpg: skipped "<key>": No secret key」や「gpg: signing failed: Inappropriate ioctl for device」です。`gpg.program` を起動できない場合、Git は「(no gpg output)」と出力します。
このエラーの意味
Git が GnuPG にコミットオブジェクトまたはタグオブジェクトへの署名を依頼したところ、gpg がエラーで終了したため、Git は処理を中断しました(「fatal: failed to write commit object」)。Git 自身の行は原因について何も示しませんが、一緒に出力される gpg の行(または `[GNUPG:]` のステータス行)が原因を示します。最も多いのは「No secret key」で、設定された `user.signingkey` がこのキーリングに存在しないことを意味します。
発生する理由
署名鍵がこのキーリングにない
よくある`user.signingkey` を別のマシン、dotfiles リポジトリ、CI の設定からコピーしたものの、秘密鍵はこのマシンに一度もインポートされていない場合です(`gpg --list-secret-keys` に表示されません)。
gpg がパスフレーズを尋ねられない
よくある`GPG_TTY` が設定されていない場合や、IDE の中、SSH 経由、CI の中では、pinentry が使えるターミナルも GUI もありません。gpg は「Inappropriate ioctl for device」またはタイムアウトを報告します。
鍵または署名用の副鍵が期限切れになっている
ときどきgpg は期限切れの鍵での署名を拒否します。stderr の行で有効期限切れが示されるか、鍵が使用できないものとしてスキップされます。
Git が別の gpg を起動している
ときどき`gpg.program` が存在しないバイナリを指している場合や、鍵が GnuPG 2 のキーリングにあるのに `gpg` 1.x を指している場合です(複数のインストールが共存する macOS でよく見られます)。
修正方法
- 1.
設定された鍵で gpg を直接実行する
同じ鍵で `gpg --clearsign` が失敗する場合、問題は Git ではなく GnuPG にあり、そのとき表示されるメッセージが本当のエラーです。
bash git config --get user.signingkey gpg --list-secret-keys --keyid-format=long # is that key listed, with a "sec" line? echo test | gpg --clearsign --local-user "$(git config --get user.signingkey)" > /dev/null && echo "gpg can sign" - 2.
存在する鍵を Git に指定し、pinentry を動作させる
ローカルに存在する秘密鍵の長い鍵 ID またはフィンガープリントを使い、`gpg.program` を明示的に設定して、シェルで `GPG_TTY` をエクスポートしてください。
bash KEY=$(gpg --list-secret-keys --with-colons alice@example.com | awk -F: '/^sec/ {print $5; exit}') git config --global user.signingkey "$KEY" git config --global gpg.program "$(command -v gpg)" export GPG_TTY=$(tty) # in ~/.bashrc / ~/.zshrc, so pinentry can ask for the passphrase
関連するエラー
gpg: signing failed: Inappropriate ioctl for deviceGit commit signing with GnuPG 2error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh sign…Git (verify-commit, log --show-signature, merge --verify-signatures) with gpg.format=sshgpg: Can't check signature: No public keyGnuPG (gpg --verify, git verify-commit / verify-tag / log --show-signature)