【初心者向け】git rebaseの基本
背景
エンジニアとしてGitを利用して仕事をしているとよく「リベースしてください」と言われることが多いです。
リベースして、コンフリクトしていると言われ、調べたままコマンドを打っていくとどんどんよくわからなくなっていき、大惨事を招くといったことがあったので、かつての自分に向けての記事としてまとめたいと思います。
git rebase とは何をしてくれるコマンドなのか
普通mainから新しく変更をするために枝を生やす(ブランチを作成する)ときは、下記のように打って枝を生やすと思います。
git checkout -b 作成したブランチ main
枝を生やした際に、自分の作業が遅くて、他のメンバーは早く開発して次々とマージされていくので、どんどんmainが進んでいってしまいます。
git rebase main
そんな時に、rebaseをすると、自分のブランチを最新のメインの先頭に付け替えてくれます。
コンフリクト案件が発生することがある
rebaseをした時に、他のメンバーが修正した箇所と、自分が修正している箇所とが被ってしまうと、コンフリクトが発生します。
そんなときはコンフリクト案件解決ゲームが開始されます。
CONFLICT (content): Merge conflict in db/schema.rb
(中略)
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
それではコンフリクト案件解決ゲームを解説していきましょう。
git rebase をしてコンフリクトした時の基本的な流れ
- コンフリクトしたファイルを確認
<<<<<<<< HEAD (Current Change)
現在取り込もうとしている内容
=====
自分の変更内容
>>>>>>>> <コミットメッセージ> (Incoming Change)
コンフリクトしたと書いてあるファイルを見てみると、上記のようなメッセージが表示されるので、どちらをかを選びましょう!
- コンフリクトを解消
【自分のを優先させる】
自分のが正しいんだ!という場合は、上のようなファイルから取り込もうとしている内容と、コンフリクトの>>>や===のマークを消して、
自分の変更内容
だけを残しましょう!
【取り込み先のを優先させる】
反対に、いやぁ先輩の方が正しいっすよね、、という場合は、自分の変更内容と、コンフリクトの>>>や===のマークを消して、
現在取り込もうとしている内容
だけを残しましょう。
- セーブする
その後は、「git add」でコンフリクト解消をセーブしていきましょう。
git add コンフリクトを解消したファイル
rebaseする際は、「git commit」をしないので注意しましょう!
それでは、「git status」コンフリクトの解消状態を確認してみましょう。
git status
とすると、
You are currently rebasing branch 'main2' on 'aaaaa'.
(all conflicts fixed: run "git rebase --continue")
nothing to commit, working tree clean
こいつ、「nothing to commit, working tree clean」が出たら、コンフリクト解消はできています。
- 完了させる
それでは、次に、rebaseを完了させます!
git rebase --continue
をすると、
Successfully rebased and updated refs/heads/main2
無事にrebaseが完了されました!
コンフリクトを解消した時の注意(push)
コンフリクトを解消した後に、注意するのが、pushをする時です!
普通にpushをしようとすると、下記のようなエラーメッセージが出ます。
To github.com:mode/hogehoge.git
! [rejected] main2 -> main2 (non-fast-forward)
error: failed to push some refs to 'github.com:mode/hogehoge.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
つまり、今のリモートのブランチは遅れているよ!って言われています。
ですが、ちゃんとrebaseをしてコンフリクトを解消しているので、
強制的に、pushしてしまって問題ないです!
git push --force origin HEAD
これで、ちゃんと先頭に枝の根元を付け加えることができました!
Discussion