思い通りにいかなかった。
やりたいこと
git push
を実行した際に上流ブランチがないと下記のエラーが発生します。
fatal: The current branch feature/hogehoge has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin feature/hogehoge To have this happen automatically for branches without a tracking upstream, see 'push.autoSetupRemote' in 'git help config'.
上記のエラーを確認してから打ち直すのが面倒なので、自動化をしようと試みました。メッセージに従って
git config --global --add --bool push.autoSetupRemote true
と実行すれば自動で上流ブランチの作成まで行なってくれる*1のですが、心理的に一度確認を挟んでから作成するようにしたいと考え、別の手段を検討しました。
pre-pushではできない
Git フックで上記を実現できないかなと思い、下記のようなスクリプトを(Copilotが)作成しました。
#!/bin/zsh # 現在のブランチ名を取得 current_branch=$(git rev-parse --abbrev-ref HEAD) # リモートブランチが存在するか確認 if git show-ref --verify --quiet refs/remotes/origin/$current_branch; then # リモートブランチが存在する場合、通常のpushを実行 exit 0 else # リモートブランチが存在しない場合、ユーザーに確認 echo "Remote branch does not exist. Do you want to create and push to it? (y/n)" read answer if [[ $answer =~ ^[Yy]$ ]]; then # ユーザーがyesを選択した場合、ブランチを作成してpush git push --set-upstream origin $current_branch exit 1 fi fi
しかし、上記のスクリプトは動きません。git push
を実行しても上記のスクリプトが実行される気配がありません。動かない原因はシンプルで、pre-push
がトリガーされていないためです。pre-push
のフックは実際に何かがプッシュされる前にトリガーされるため、リモートブランチが存在しない場合はgit push
は何も行わず、結果としてpre-push
もトリガーされないのです。
Gitのドキュメントにもそのように記載があります*2。
pre-push フックは、 git push を実行した際、リモート参照が更新された後、オブジェクトの転送が始まる前に実行されます。
カスタムコマンドを作るしかない
上記を解決するために、下記のカスタムコマンドを(Copilotが)作りました。
#!/bin/zsh current_branch=$(git rev-parse --abbrev-ref HEAD) remote_branch_exists=$(git ls-remote --heads origin $current_branch) if [ -z "$remote_branch_exists" ]; then echo "Warning: The remote branch does not exist." echo "Would you like to create it? (y/n)" read answer case $answer in [yY]* ) git push --set-upstream origin $current_branch;; * ) echo "Aborting push."; exit 1;; esac else git push fi
こうすることでやりたいことが実現できましたが、Git フックで実現できないのは少しモヤモヤしますね。。git push
のエイリアスでこのスクリプトを利用しようとは思わない(もちろんオプションも与えて実行できるようにする前提で)ですし、、