ちぎっては投げるブログ

Programming, Android, RaspberryPi, Digital Devices, Kinkuma Hamster...

git push -f を捨てよ、--force-with-leaseを使おう

japan.blogs.atlassian.com

そもそも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 --force-with-leaseする前にfetchをしていると、pushが成功してしまう(つまり上書きしてしまう)。

しかし、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も使っている。

ターミナル上では見やすいのだが、差分をコピーして他のエディタに移す+-がないためわかりにくいので、乗り換えようかと検討している。