マンガでわかるGit 11話「強制プッシュするとどうなるの?プッシュできないときはどうすべき?」

強制プッシュしようとして、魔王教授に止められたわかばちゃん。
「むやみに強制プッシュするのはダメ」ということはわかったけれど、やると具体的にどんなことが起きるのでしょう?
そして、pushできない状態に陥った瞬間、本来ならわかばちゃんはどうすべきだったのでしょう?

強制プッシュするとどうなるの?プッシュできないときはどうすべき?

☆ 前回のお話はこちら:「masterブランチを守れ!~危険な強制プッシュ~


さっきの状態を再現してみたわ。


この状態では何も問題ないわね。


ここでわかばちゃんは、masterブランチの内容を修正しようとして、プッシュ済みのコミットDをコミットXに書き換えてしまった。


そうそう。さっきそれをやっちゃったんだよね。
そしたら、なぜかプッシュできなくなった。
なんで?


その理由は、図で表すとこうよ

◎ 正常にpushできる状態

EはDの子孫

* リモートリポジトリのmasterと、ローカルリポジトリのmasterがきれいな
  親子関係になっている
* = 正常にpushできる

× 普通の方法ではpushできない状態

YはDの子孫じゃない

* リモートリポジトリのmasterの最終コミットと、ローカルリポジトリの
  masterの最終コミットが親子関係になっていない
* = エラーになりpushできない
  (このまま強引にpushするとDが履歴から消滅してしまう)

強制プッシュはなぜダメか

チームで共有しているブランチで、強制プッシュ(push -f)してしまうと、自分はよくても、自分以外のメンバーがプッシュできなくなってしまいます。

2~3人のチームならすぐさま連絡すればどうにかできますが、チームの規模が大きくなればなるほど、被害が増えてしまいます。

強制プッシュが許されるのは、原則「自分しか利用していないリモートブランチだけ」です。

共有しているブランチで修正したくなったら?


もし、他の人と共有しているブランチの内容を修正したくなったらどうすればいいの?


過去のコミットを書きかえずに、新しいコミットを上に積むだけにしておいて。


そっか。そうすれば親子関係は書きかわらないし、他のメンバーはその新しいコミットだけ後からマージすればいいんだもんね。

「pushできなくなった!」そんなときはどうすべき?


「pushできないな」と気付いた瞬間に、本来やるべきことってなんなんだろう? もちろん強制プッシュじゃなくて。


次のように対処するといいわ。そのときの状況やチームの方針もあるから、メンバーにひと声かけてから実行したほうが安心ね。

自分の作業履歴をバックアップした上で、リモートからローカルへmasterを上書きする

① まず、今作業してるブランチからtmpというブランチを切ります。

$ git branch tmp

(元の作業ブランチはいじらずに温存しておきます)

②masterブランチにチェックアウトします。

$ git checkout master

③リモート追跡ブランチを最新にして

$ git fetch

④ローカルブランチのmasterを、リモート追跡ブランチのmasterに強制的に上書きします。

$ git reset --hard origin/master

ここからは

  • A: プルリクエストを作りたい場合
  • B: masterブランチにコミットを積みたい場合

で手順が異なります。

A: プルリクエストを作りたい場合

$ git checkout tmp
$ git rebase master    //または git merge master
$ git push origin tmp

最後にGitHub上でtmpブランチからプルリクを作って完了です。

B: masterブランチにコミットを積みたい場合

$ git merge tmp
$ git push origin master

プルリクはせずに、masterブランチに単にコミットを積みたい場合はこれで完了です。

まとめ

強制プッシュが危険な理由

  • 自分はよくても、自分以外のメンバーがプッシュできなくなってしまい、作業に支障が出るため

過去のコミットを書き換えてしまって、プッシュできなくなったらどうすればいい?

  • まず、自分の作業履歴を新規ブランチに一時退避し、リモートからローカルへmasterを上書きする
  • その後、リベースしてプルリクエストを出すか、マージしてプッシュする

次回予告 ~フォークしたリポジトリを本家リポジトリに追従させよう~


次回は、フォークしたリポジトリを本家リポジトリに追従させる方法について学んでいこう。


たしかに、そのやり方がわからないっていう質問、多いのよね。


あ!それ、私も知りたい!「フォークしたはいいけど、本家のリポジトリのコミットが進んじゃって、自分のリポジトリは古いまま」っていう悲しい状態になってるんだよね。

次回のマンガでわかるGitは、「本家リポジトリの追従」をやります!

登場人物紹介

マンガ・解説文:湊川あい
絵を描くWebデザイナー。高等学校教諭免許状 “情報科” 取得済。マンガと図解の力で、物事をわかりやすく伝えることが好き。2014年より「マンガでわかるWebデザイン」をインターネット上に公開していたところ、出版社より声がかかる。著書に「わかばちゃんと学ぶ Webサイト制作の基本」・わかばちゃんと学ぶ Git使い方入門わかばちゃんと学ぶ Googleアナリティクス〈アクセス解析・Webマーケティング入門〉
Twitter: @llminatoll
Webサイト: マンガでわかるWebデザイン

監修:DQNEO
株式会社メルカリではたらくソフトウェアエンジニア。
アメリカ版メルカリのサーバサイドを開発している。
GitとPHPが大好き。Goも好き。
Twitter: @DQNEO
Github: @DQNEO

※この記事は2017年1月時点における実施内容です。時期・環境・バージョンによって、操作が異なることがあります。

Pagetop