Git と Visual Studio 2017 その 6 : リベースで他のブランチからコミットを反映

前回の記事ではブランチ間のマージを紹介しました。今回は似て非なる機能としてリベースを見ていきます。

リベース : Git

リベースはマージと何が違うのでしょうか。例えば dev を切ってコミットを追加した後、何かしらの事情で master にもコミットが作成された場合を考えます。

  • マージ: dev から master をマージすると master のコミットが、現在の dev のコミットの後に適用されます。
  • リベース: master のコミットが dev のコミットの前に入るため、あたかも master でが作成された後に dev を切ったような状態となります。

実際にやってみましょう。

1. ‘git log --oneline --graph’ を実行して現在の状況を確認。前回の記事の直後のためマージコミットが最後に存在。

image

2. マージ前に戻すため、‘git reset --hard c79adb2’ を実行し、再度 ’git log --oneline --graph --all’ を実行。

image

3. この時点で Visual Studio 2017 より Patch1.cs を追加。全て保存。

image

4. ‘git add VS_Git\Patch1.cs’ および ‘git commit -am “Patch1.cs の追加”’ を実行。

image

5. ‘git log --oneline --graph --all’ を実行。dev ブランチと別に master にも新しいコミットが存在。

image

6. リベースは dev ブランチから行うため、’git checkout dev’ を実行してから ‘git rebase master’ を実行。Git が csproj ファイルでの競合エラーを出力。これは master ブランチの csproj ファイルは Patch1.cs の情報を持っているが、dev ブランチの初めのコミットは Class5.cs を持っているため。

image

7. ‘git mergetool’ を実行してマージ用のツールを起動。Visual Studio が構成されている場合 VS が起動する。

image

8. Source では Class5.cs だけが表示され Class6.cs が表示されないが、これはリベースがコミットを 1 つずつ適用するため。今回は両方の変更をチャックボックスをクリックし選択後、”マージの許可” をクリック。

image

9. 競合の解消が終わったので、‘git rebase --continue’ を実行してリベースを続ける。するとまた競合。今度は dev のコミット 2 つ目だが先ほどと同じ理由。

image

10. 'git mergetool’ を実行してマージツールを起動。

image

11. 期待通り、今回は Class6.cs が存在。両方を選択して、”マージの許可” をクリック。

image

12. ‘git rebase --continue” を実行。もうエラーが出ないことを確認。

image

13. ‘git log --oneline --graph --all’ を実行。グラフが一列に表示され、Patch1.cs の追加が dev のコミットより前に入ることを確認。しかし親コミット ID が変わるため Git としては新しい Git オブジェクトが作成され、結果コミット ID は変わる事を確認。

image

14. Git はオブジェクトをすぐには削除しないため、‘git reset --hard 5df97d2’ を実行すると dev は前のコミットをポイントする為リベース前にリセットされる。‘git log --oneline --graph --all’ を実行して確認。

image

リベース : VS

次に Visual Studio 2017 のリベースを見ていきます。

1. チームエクスプローラー | 変更 | アクション | 履歴の表示より履歴を確認。残念ながら -all オプションに該当する機能が見当たらず特定のブランチ履歴しか見れないため master、dev ともに確認。

2. ブランチメニューより dev をチェックアウトし、リベースをクリック。

image

3. 対象ブランチで master を選択し、”リベース” をクリック。

image

4. Git でのテストから期待した通り、競合のメッセージが出現。”競合: 1” リンクをクリック。

image

5. 競合の解決画面に遷移。すべての競合が表示されるが今回は 1 つだけのため、VS_Git.csproj をクリック。”マージ” ボタンをクリック。

image

6. マージツールが起動するので、競合を解消。

image

7. 競合が無いことを確認して、”変更を表示” をクリック。

image

8. 現在の状況が表示されているがここではコミットは必要がないため、”進行中のリベース” セクションの ”続行” リンクをクリック。

image

9. 期待通り、2 つ目の競合が表示される。”競合: 1” リンクをクリック。

image

10. 同様に競合を解消。再度 ”続行” リンクをクリック。

image

11. リベースが完了したら履歴を更新。

image

まとめ

リベースを理解する前は、なぜ競合が何度も出るかや競合解消後の進め方が分からず、断念することがありましたが、今は安心してリベースが行えます。また Git オブジェクトが削除される前であれば、簡単にリベースの前段階に戻すこともできます。

途中で分からなくなった場合、’git rebase --abort’ または Visual Studio 2017 から中断を行えば、初めからやり直しが可能です。次回はチェリーピック機能を見ていきます。次の記事へ

中村 憲一郎