雑メモです。
git で force push したいけど、操作を誤っていないか毎度ビクビクしてしまう。
そんな心労に少しでも楽になる方法を考えてみました。
私の事例で恐縮ですが、force push する際に怖いのは...
- 誤ったブランチを指定してしまう
- 共同開発してるブランチで, 相方のコミットを吹き飛ばしてしまう
この2点が代表的だと思います。
1点目に関しては、大切な main (master) や, topic といったマージコミットのみを集合とするようなブランチは、そもそも git push による直接更新をできないようにしておくべきでしょう。 ブランチ保護機能を有効にします。
Github の設定方法
Gitlab の設定方法
2点目に関しては, force push する場合のオプション指定でほとんどの場合をカバーすることが出来るでしょう。 *1
具体的には, git push --force-with-lease --force-if-includes branch名
とするようにします。
長いので alias 貼っておきましょう。
git config --global alias.pushf 'push --force-with-lease --force-if-includes'
...
# git pushf <ブランチ名>
--force-with-lease オプションについて
git push -f をやめて --force-with-lease を使おう
しかし, git fetch を行った後だと 誤ったforce push が出来てしまう点が課題でした。
--force-if-includes について
Git Reference
When should I use "git push --force-if-includes"
--force-with-lease の課題である fetch後の誤ったforce push を回避するオプションになります。
上記の設定をしておくことで、少しでも安心して作業ができるのではないでしょうか。
fishシェル特有の悩み
余談ですが、 fishシェルはありがたいサジェッションのおかげで過去に入力したコマンドを素早く再入力できるのですが、
force push を行う際に異なるブランチ名がサジェストされがちで、気をつけないと行けません。
(作業してるブランチと異なる別ブランチにpushしてしまう可能性がある)
回避策として以下のコマンドを自作しました。
特徴はとしては2点。
- push先のブランチ名が作業ブランチと異なると怒ってくれる。
- force push オプションに --force-with-lease --force-if-includes を付けていること。
あえてブランチ名を要求することで、脳死で打たせないようにしています。
function gpf --wraps='git push origin' --description 'gpf is git push origin force'
set -l targetBranch $argv
set -l currentBranch (git branch | grep -E "^\*" | cut -c 3-)
if test $currentBranch = $targetBranch
git push --force-with-lease --force-if-includes origin $targetBranch
echo "done 👍"
else
echo ""
echo \
""" Careful!!
Make sure you push to the same branch you are checking out now."""
echo " you: $currentBranch , push to: $targetBranch"
end
end
上記の関数を $HOME/.config/fish/functions に保存します。
git repository 配下で以下のようなコマンドで実行出来ます。
gfpじゃないのはご愛嬌ということで...
gpf <ブランチ名>
*1 コメントで頂いた内容を反映しました。