Bitbucket:「remote: Commit signature verification failed」
リポジトリは push するすべてのコミットに確かめられる署名を求めていて、今回の push の中に、署名が無いか、Bitbucket が確かめられない署名のコミットが1つ以上あります。Bitbucket 側は何も変わっていません。手元でコミットに署名して、もう一度 push します。文面の全体は、Atlassian の記事 Troubleshooting common Bitbucket Cloud GPG key issues to use signed commits(英語)のとおりです。
remote: Commit signature verification failed To https://bitbucket.org/<workspace>/<repo>.git ! [remote rejected] branch -> branch (pre-receive hook declined) error: failed to push some refs to 'https://bitbucket.org/<workspace>/<repo>.git'
元になっている設定
Atlassian の署名済みコミットを必須にするは、Premium のワークスペースの機能です。リポジトリの管理者が、Repository settings の Repository details、Advanced で Require all commits to have a verified signature を有効にします。それからは、署名の無いコミットや、確かめられない署名のコミットが1つでもあると、push は失敗します。リポジトリにすでにあるコミットはそのままです。
同じページによると、Bitbucket の画面でマージしたプルリクエストは確かめの対象になりません。Atlassian の SSH の署名のページは、画面で作ったコミットと、Bitbucket がプルリクエストをマージするときの方法(merge strategy)で作ったコミットを「No signature」としています。
「Commit signature verification failed」の行が無く、「pre-receive hook declined」だけで断られたときは、たいていブランチの制限が原因です(「pre-receive hook declined」)。
署名の無いコミットを見つける
git log --format='%h %G? %s' origin/main..HEAD
N は署名なし、G は正しい署名です。SSH の署名は、許可した署名者のファイル(allowed signers)と照らして確かめます。このファイルが無い状態で試すと、Git は次のように出し、署名したコミットまで N と表示しました。
error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification
種類を問わず、コミットに署名が付いているかどうかだけを見るなら、git cat-file commit <コミット> に gpgsig の行があるかを見ます。
署名をし直す
git rebase -f -S origin/main
git push
origin/main より後のコミットを、全部署名つきで作り直します。-f は外せません。試すと、git rebase -S だけでは Current branch t2 is up to date. と返り、何も署名しませんでした。ブランチにマージのコミットがあるときは --rebase-merges を足します。試したマージのコミットも署名つきになりました。コミットの ID は変わりますが、Bitbucket は断っていて1つも持っていないので、ここでは問題になりません。
これからのコミットに -S なしでも署名するには、こう設定します。
git config --global commit.gpgsign true
この設定が無いと、試したコミットの署名は git commit --amend で消えました。
Bitbucket が確かめられる署名
Bitbucket は、アカウントに登録した鍵で署名を確かめます。コミットのメールアドレスも合っている必要があります。
- GPG(GPG キーを使ってコミットに署名する):Bitbucket のアカウントのメールアドレスで
gpg --full-generate-keyを使って鍵を作り、公開鍵を Personal Bitbucket settings の GPG keys に登録して、git config --global user.signingkey <鍵の ID>で Git に教えます。 - SSH(SSH キーを使ってコミットに署名する・Git 2.34 以降):
git config --global gpg.format sshとgit config --global user.signingkey ~/.ssh/id_ed25519.pub。Bitbucket への認証に使っている鍵でも署名できます。
Bitbucket はコミットを Verified、Unverified、No signature のどれかで表示します。SSH のページによると、Unverified になるのは、メールアドレスが合わないとき、鍵がどの Bitbucket のアカウントにも無いとき、鍵が対応していないか、消されたか、取り消されたときです。どちらのページも、今のところ確かめられるのはコマンドラインから push したコミットだけとしています。
Git が署名できないとき
先のトラブルシューティングの記事から:
error: cannot run gpg: No such file or directory:GPG が入っていないか、Git が見つけられません。入れるか、git config --global gpg.program "$(which gpg)"を設定します。error: gpg failed to sign the dataとfatal: failed to write commit object:鍵の期限が切れているかもしれません(GPG はUnusable secret keyと出します。gpg --edit-key <鍵の ID>のexpireで延ばします)。または、user.signingkeyが別の鍵を指しています。- Mac で Homebrew の GPG なら、
gpg: signing failed: Inappropriate ioctl for deviceも出ます。記事はGPG_TTYを設定し、パスフレーズの入力にpinentry-macを入れています。
IntelliJ IDEA から署名する
JetBrains のGPG キーを使用してコミットに署名するによると、Settings の Version Control、Git で Configure GPG Key を押し、Sign commits with GPG key を選びます。GPG はパスフレーズを pinentry の窓で聞くので、窓を出す pinentry が要ります。ページは echo GETPIN | pinentry で確かめています。Windows では、Git for Windows 2.19.2 以降に GPG が入っています。
IntelliJ IDEA から Bitbucket のプルリクエストを作るなら
Pull Request Inbox for Bitbucket は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。Bitbucket Cloud と Data Center で、Git メニューに Bitbucket のプルリクエストを作成… を足します。今いるブランチから、選ばなければリポジトリのメインのブランチへ、プルリクエストを作ります。ブランチがまだ Bitbucket に無ければそう伝えて、先に IDE の push の画面を開きます。プルリクエストの作成・承認・マージは Pro(月 US$1.50・30日間の無料試用つき)、受信箱は無料です。画面は日本語です。
Bitbucket と Atlassian は Atlassian の商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは Atlassian・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:ブランチの制限で出る「pre-receive hook declined」 · IntelliJ IDEA の Bitbucket プルリク用プラグインの比較 · English