39 | 統合ブランチへの push -f 操作の禁止#
-f /--force:強制更新
シーン:ローカルとリモートが fast-forwards 関係でない場合、ローカルは本来リモートにプッシュすることができませんが、git push -f
コマンドを使用すると、ローカルを強制的に更新してリモートにプッシュできます。
デモ:リモートの commit を強制的に消去します。
まず、現在のリモートの commit 履歴を見てみましょう:
そしてローカルの commit 履歴:
この時、ローカルのバージョンを以前の commit、例えば f21c98a にリセットし、git reset --hard f21c98a
を実行します。その後、ローカルの commit 履歴を再度確認します:
その後の commit 履歴が消えていることがわかります。
この時、再度プッシュを行います:
直接 git push
は確実に失敗しますが、-f
を付けることで成功しました。再度リモートの commit 履歴を見てみましょう:
いいえ!もしあなたがリモートの別の開発者であれば、ここを見た時の気持ちはどうでしょう?
では、このような操作を防ぐためのメカニズムは何でしょうか?自分で調べてみてください。Github と Gitlab はそれぞれ相応の保護メカニズムを提供しています。
📢さらに、git reflog
を使用して、先ほど失ったブランチを取り戻すこともできます。以下の図の赤枠部分を参照してください:
そして git reset --hard HEAD@{n}
を利用して復元します~
40 | 統合ブランチへの履歴変更操作の禁止#
チーム内の共有ブランチでは rebase 操作を厳禁とします
例えば:
同僚 A が rebase を通じて commit のメッセージを変更し、リモートにプッシュしました:
彼は 2 つの commit のメッセージに [feature] のプレフィックスを追加しました。
一方、同僚 B は彼の変更前に、origin/temp ブランチを基に同様に test_rebase_inter ブランチを作成し、2 回新しい commit を提出しました:
この時、同僚 B は自分の更新をプッシュしようとすると、必ず問題に直面します。
さらに、すでに test_rebase_inter ブランチで開発を行っている他の同僚もこの問題に直面し、彼らも再度 rebase を使用して処理する必要があり、これにより多くの不必要なトラブルが生じます。
または、同僚 A を見つけて元に戻してもらう方法もあります。具体的な方法は前のセクションで言及した git reflog
の方法を参照してください。
rebase の適用シーンの一つ:リモートにプッシュしていない状態で、rebase を通じてローカルの複数の commit を 1 つの commit にまとめてからプッシュします。
統合開発では、2 つのポイントを忘れないでください:push -f しないこと;リモートの履歴を変更しないこと。