深夜2時のコミット失敗
夜遅く、重要なバグ修正という過酷な作業を終えたところだとしましょう。git commit -m "Fix: resolve race condition" と入力して Enter キーを押し、成功メッセージを待ちます。しかし、Git は無情にも次のようなエラーを返してきます。
error: gpg failed to sign the data
fatal: failed to write commit object
このエラーは内容が曖昧なため、非常に厄介です。コードが間違っていることは稀で、通常は Git が署名のために GPG を呼び出そうとしたものの、GPG がパスフレーズを要求する方法を見つけられなかったことを意味します。つまり、ターミナルと暗号化エンジンの間の通信トラブルです。
なぜ GPG に無視されるのか
Git 自体はパスワード入力を処理せず、その仕事をエージェントに任せます。この連携が失敗する主な理由は以下の通りです。
- TTYの欠如: GPG がパスワードプロンプトを表示すべきターミナル画面を認識できていない。
- エージェントの不具合: バックグラウンドで
gpg-agentがハングしているか、クラッシュしている。 - パスの不一致: 複数の GPG バージョンがインストールされており、Git が誤った方を呼び出している。
- 鍵の期限切れ: GPG 鍵が有効期限(通常は作成から1〜2年)に達している。
「今すぐプッシュしたい」時の応急処置
急いでいる場合は、手動で GPG に現在のターミナルを教え、バックグラウンドデーモンを再起動することで解決することが多いです。以下の3つのコマンドを実行してください。
export GPG_TTY=$(tty)
gpgconf --kill gpg-agent
gpg-agent --daemon
もう一度コミットを試してください。パスフレーズ入力用のポップアップまたはターミナルプロンプトが表示されるはずです。これで解決すれば良いですが、明日また同じことが起きないように、以下の恒久的な対策を行うことをお勧めします。
恒久的な解決策
1. GPG_TTY 変数の自動設定
これは Linux および macOS ユーザーにとって最も効果的な修正方法です。シェルに対して、GPG 用の表示ターミナルを常に定義するよう設定する必要があります。プロファイル設定ファイル(Mac/Zsh の場合は ~/.zshrc、Bash の場合は ~/.bashrc)を開き、末尾に以下の行を追加します。
export GPG_TTY=$(tty)
ファイルを保存し、source ~/.zshrc を実行してセッションを更新してください。
2. macOS と Linux での Pinentry の設定
GPG は pinentry という小さなユーティリティを使用してパスワード入力ボックスを表示します。macOS では、Homebrew がこれを GPG がデフォルトでチェックしない場所にインストールすることがあります。そのため、明示的に指定する必要があります。
~/.gnupg/gpg-agent.conf を作成または編集します。
# Apple シリコン搭載 Mac (M1/M2/M3) の場合
pinentry-program /opt/homebrew/bin/pinentry-mac
# Intel 搭載 Mac の場合
# pinentry-program /usr/local/bin/pinentry-mac
# Linux (サーバー/ヘッドレス環境) の場合
# pinentry-program /usr/bin/pinentry-curses
保存後、エージェントを再起動します: gpgconf --kill gpg-agent
3. 鍵の有効期限を確認する
設定が完璧でも、鍵自体の期限が切れている場合があります。以下のコマンドで鍵の状態を確認してください。
gpg --list-secret-keys --keyid-format LONG
sec rsa4096/3AA5C34371567BD2 2022-01-01 [SC] [expired: 2024-01-01] のような行を探してください。「expired」と表示されている場合は、期限を延長する必要があります。
gpg --edit-key 3AA5C34371567BD2
gpg> expire
# プロンプトに従って 1y または 2y を入力
gpg> save
4. Windows 特有の修正 (Git Bash)
Windows では、Git に独自の GPG が同梱されていることがあり、それが Gpg4win と競合する場合があります。実行ファイルを直接指定して、Git に正しいバージョンを使用させます。
git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
最終確認
ダミーの変更に対して署名付きコミットを強制実行し、パイプラインをテストします。
git commit -S -m "Testing GPG fix"
git log --show-signature -1 で結果を確認します。gpg: Good signature と表示されれば、設定は正常に修復されています。これで深夜の悩みに煩わされることなく、コードのデリバリーに戻ることができます。

