ローカルにWIPコミットがあったらgit pushを止める

に公開

ローカルで実験的にやっている作業をpushしたくないな〜と思って調べました。

Git本来のフック機能(.git/hooks/pre-push)を使えそうかな?と思いCopilotに聞いたのですが、各リポジトリで設定しなければならず、グローバルにフックを設定することはできないとのこと。

代わりにサブコマンドを用意する方法を提示されました。
まず、git log origin/$(git rev-parse --abbrev-ref HEAD)..HEAD --onelineで未pushのコミットを一覧できます。そして、gitはPATHにgit-xxxというスクリプトを置くとgit xxxの形式で実行できる機能があります。これらを利用して、次のようにpush-with-checkというスクリプトを作ればgit push-with-checkというサブコマンドを作ることができます。

my-bin/git-push-with-check(executable)
#!/bin/bash

if git log origin/$(git rev-parse --abbrev-ref HEAD)..HEAD --oneline | grep -i "wip"; then
  # display error message in red
  echo -e "\n\033[31mError: Found 'wip' in local commit. Please fix before pushing.\033[0m"
  exit 1
fi

git push

とはいえ、これだといちいちgit push-with-checkと打たないといけません。が、そもそも筆者は普段からpushというシェルエイリアスを使っていて、git pushとは打っていないことを思い出しました。このエイリアスを書き換えたらええやん!

shell config
-alias push='git push'
+alias push='git push-with-check'

これで、(筆者としては)ワークフローを大きく変えなくてもwip確認が動くようになりました。ローカルにwipのついたコミットがあると警告が出てきます。

さらに、筆者はlazygitを使っているので、こちらからもpush-with-checkを使えるよう修正を入れます。Pキーがpushに割り当てられているので、これを上書きします。

/path/to/lazygit/config.yml
customCommands:
  - key: 'P'
    context: 'global'
    command: 'git push-with-check'

(筆者は最初context: 'files'だけで十分だろうと思っていたらcommitsでも効いていて誤pushしました)

これで、lazygitのPでもwipコミットのpushを止められます。

Discussion