2015/12/29

初心者必見!Gitでやらかす前に設定しておきたいpush.default

masterブランチ、ぶっ壊しました!!


転職して1ヶ月たたないくらいのできごと。
しかも、masterブランチが変更されると自動デプロイが走って本番環境にリリースされてしまうため、直すまで生きた心地がしなかった。
こんな怖い目にあってほしくないので、ぜひgitを使う前に設定していただきたい。



何をやらかしたか?


コンフリクトをおこしたfeatureブランチをrebaseしてPullRequestを作りたかった。
その際、以下のコマンドを実行してmasterブランチを壊してしまった。
$ git push -f


具体的に何をしたのか?


1. 開発ブランチをチェックアウトし、最新化する
[master]$ git checkout develop
[develop]$ git pull --ff
※ コマンド先頭の[]で囲っているのはカレントブランチ


2. featureブランチをrebaseする
[develop]$ git checkout feature/hoge
[feature/hoge]$ git rebase develop

3. いろいろマージして、コンフリクトを解消する

4. リモートブランチにプッシュする
[feature/hoge]$ git push -f



原因は?


  • ローカルリポジトリが古い状態だった
  • config push.defaultが設定されていなかった
  • GitHub上でmasterブランチへのforce pushをプロテクトしていなかった

git pushは今いるブランチ(今回はfeatureブランチ)の内容がpushされると思っていた。
しかし、push.defaultが未設定の場合は、デフォルトで「matching」というモードになるため、ローカルとリモートの両方に存在するブランチはすべてpushされるようになっていた。



未然に防ぐためには?


config push.default を設定する

$ git config --global push.default {mode}

設定できるモードは以下の5つ

simple
初心者向けの設定。(Git 2.0以降はsimpleがデフォルトモード)
カレントブランチと同名のリモートブランチが存在する場合のみ、カレントブランチのpushが行われるモード。
私の場合は、この事故後すぐにsimpleに設定した。


matching
Git 1.xでデフォルトになっている。
ローカルとリモートの両方に存在する「すべての同名ブランチ」の差分をpushするモード。


nothing
明示的にブランチ名を指定しないとpushされないモード。
必ず「git push origin master」のようにrefspecを指定しなければならない。


current
カレントブランチを同名のリモートブランチにpushするモード。


upstream
カレントブランチに関連付けられているupstreamのブランチにpushするモード。
$ git checkout -b feature/hoge develop
# いろいろコミット

# -uオプションでupstreamを設定する
$ git push -u origin feature/hoge

# 以降はブランチ名を書かなくてもorigin(feature/hoge)にpushされる
$ git push


GitHubでforce pushを禁止する


GitHubには特定のブランチへのforce pushを無効にする機能がある。
そこでmasterブランチをプロテクトしておく。

対象のリポジトリから[Settings] → [Branches] → [Protected Branches]から設定する。




壊れたmasterブランチは?


先輩エンジニアが壊れる前のmasterブランチを持っていたので、それをpushしてもらって一件落着。
直るまでの15分間は生きた心地がしなかった。
その後、結構ヘコんでgitコマンドを使うときは、いつも以上に確認するようになった。



以上

written by @bc_rikko

0 件のコメント :

コメントを投稿