そもそもforceで上書きするなという話もあるが、master/develop以外の作業ブランチでは、developにマージリクエストを出す前に、すでにpushしているコミットを綺麗にrebaseするためにpush forceすることはある。
最初から綺麗なコミット単位のみをpush出来ればいいのだが、翌日急に休んだときに誰かが引き継げるようにとか、ローカルのデータが吹っ飛ぶ可能性を考えてバックアップの意味でpushするとか、諸々の理由をつけて作業がきちんと完結していない状態でpushすることもある。もちろん、そんなことをするのは作業ブランチ限定で、developやmasterには仮コミットはpushしてはいけないし、あとで消す仮コミットであることがわかるようにコミットログを書いておくのが良いと思う。
そうしたわけで、push -fをする機会はあるわけだが、うっかりミスで他の人のコミットを吹き飛ばした!という事態を防ぐために、git push -fを使うのはやめて、--force-with-leaseを使うようにしたい。
--force-with-leaseとは
他の人がすでにそのブランチへpushしていると、--force-with-leaseは失敗してくれる。これにより、誤って上書きするのを防ぐ。
ただし、pushする前にfetchをしていると成功してしまう。しかし、fetchしていれば何かしらの変更があったことには普通気がつくし、fetchするということはmergeもするだろうから、あまり問題は起きないだろうとは思う。
少なくとも、-fでいきなりpushするよりは事故が減るだろう。
もっとも、自分以外が操作する(それも自分が気がつかないうちに)可能性のあるブランチでforceを使う運用が良くないとは思う。
エイリアス
長くて覚えられないので~/.gitconfigにエイリアスを書いておく。
[alias] push-f = push --force-with-lease
コマンド的には以下で追加できる(はず)
git config --global alias.push-f "push --force-with-lease"
実際に使うのはこうなる。
$ git push-f origin develop
現在の私の.gitconfig
[alias] lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Crese\ t' --abbrev-commit --date=relative lga = log --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an\ >%Creset' --abbrev-commit --date=relative co = checkout br = branch ci = commit st = status pull = pull --prune fetch = fetch --prune push-f = push --force-with-lease
いつかのブログに書いたdiff-so-fancyも使っている。
ターミナル上では見やすいのだが、差分をコピーして他のエディタに移す+-がないためわかりにくいので、乗り換えようかと検討している。