MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Gitの基礎 - rebaseとmergeの使い分けのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Gitの基礎 - rebaseとmergeの使い分け
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == Gitにおいて、mergeコマンドとrebaseコマンドは、異なるブランチの変更を統合するためのコマンドである。<br> しかし、統合の方針に違いがある。<br> <br> ここでは、masterブランチの過去のコミットから派生した機能開発用のtopicブランチの変更を、masterブランチに取り込むという状況で、2つの方法を比較する。<br> <br><br> == merge / rebaseの主な違い == ==== 履歴の形状 ==== * merge *: ブランチの履歴がそのまま保持されて、マージコミットによって結合点が作られる。(木構造) * rebase *: コミットを付け替えることにより、直線的な履歴になる。 <br> ==== コミットの同一性 ==== * merge *: 元のコミットのSHA-1ハッシュが保持される。 * rebase *: 新しいコミットが作られるため、SHA-1ハッシュが変更される。 <br> ==== コンフリクト解決 ==== * merge *: マージ時に1回だけコンフリクトを解決する。 * rebase *: 付け替える各コミットにおいて、潜在的にコンフリクトが発生する可能性がある。 <br><br> == mergeを使用すべき場合 == * フィーチャーブランチの履歴を残す場合 * 既にリモートで共有されているブランチの場合 * コンフリクト解決を1度で済ませる場合 * チーム開発で作業の証跡を残す場合 <br><br> == rebaseを使用すべき場合 == * 直線的な履歴が必要な場合 * ローカルでのみ使用しているブランチの場合 * 細かい作業履歴を整理する場合 * master / mainブランチの最新変更を取り込む場合 <br><br> == Publicブランチでのrebase禁止 == 既にプッシュされたブランチをrebaseする場合、他の開発者の環境で問題が発生する。<br> <br> # 絶対に避けるべき操作 git checkout main git rebase feature <br><br> == rebase後のプッシュ == <code>--force-with-lease</code>オプションとは、他の開発者が同じブランチを更新していないことを確認できる安全なオプションである。<br> <br> # rebase後に強制プッシュが必要 git push --force-with-lease origin feature <br><br> == マージ戦略の一貫性 == チーム内で統一されたマージ戦略を実施することが重要となる。<br> <br> # マージコミットを必ず作成する場合 git merge --no-ff feature # rebaseした後にマージする場合 git checkout feature git rebase main git checkout main git merge --ff-only feature <br><br> == 推奨される方法 == ==== 作業開始時の基点更新 ==== git checkout main git pull git checkout -b feature # 作業開始 <br> ==== 定期的な同期 (rebaseの場合) ==== git checkout feature git rebase main # コンフリクト解決 git push --force-with-lease origin feature <br> ==== マージ前の履歴整理 ==== # コミットを整理 git rebase -i HEAD~3 # スカッシュマージ git merge --squash feature <br><br> == mergeを使用して統合する == 下図のように、topicブランチで開発する間において、masterブランチのコミットが先に進んでいるとする。<br> この時、materブランチにtopicブランチをmergeすると、コンフリクト (競合、衝突) が発生する。<br> [[ファイル:Git Merge Rebase 1.png|フレームなし|中央]] <br> しかし、masterブランチ上でコンフリクトを解決するのは好ましくない。<br> これは、解決の結果が正常に動作するかどうか実証する必要があるからである。<br> <br> そこで、まず、コンフリクトの解決の実証をローカルのtopicブランチで行うため、masterブランチ側の変更をtopicブランチにmergeする。<br> topicブランチに取り込むことにより、コンフリクトを解決する。<br> <br> 次に、masterブランチをチェックアウトして、topicブランチの変更をmasterブランチにmergeする。<br> この時、--no-ffオプションを付加しない限りは、fast forward mergeとなる。<br> <br> これにより、topicブランチのコミットと完全に同一のコミット (sha-1が同じ) が、masterブランチのコミットとして記録される。<br> <br> チーム開発の場合、masterブランチへの最終マージにおいては、masterブランチの管理者に対してプルリクエストを送信して実施してもらう場合もある。<br> <br><br> == rebaseを使用して変更の起点を移動する == rebaseは、再度(re)起点を定める(base)という意味合いがある。<br> <br> 下図に、最初の状態 (rebase前) を示す。<br> mainブランチとtopicブランチが分岐しており、両ブランチで並行開発が行われているものとする。<br> [[ファイル:Git Merge Rebase 2.png|フレームなし|中央]] <br> まず、統合前の状態では、masterブランチとtopicブランチの間にコンフリクトが発生する。<br> それを避けるため、topicブランチの起点をmasterブランチの最新のコミットで置き換える。<br> <br> コンフリクトがあれば個別に解決する必要がある。<br> <u>rebaseでは、topicブランチのコミットを1つずつ順番にmasterブランチの最新の先端に付け加える処理が発生する。</u><br> <br> 例えば、topicブランチ上において、masterブランチとコンフリクトが発生するファイルを何度も繰り返し変更している場合は、その都度、競合が発生する。<br> そのため、コミットの多いtopicブランチをrebaseする場合は作業が煩雑になる。<br> 事前に、topicブランチの履歴を<code>rebase -i</code>コマンド等を実行して簡略化すると緩和できる。<br> <br> # topicブランチの起点が、mainブランチの最新コミットに移動する。 # topicブランチのコミットが順次適用されて、新しいコミット (3'、6'、8') として再作成される。<br>この過程でコンフリクトが発生する可能性があり、その都度解決が必要となる。 [[ファイル:Git Merge Rebase 3.png|フレームなし|中央]] <center>図. rebase後の状態 (topicブランチの起点が移動)</center><br> <br> ここでは、rebaseした後のコンフリクトの解決と実証が正常に終了したものとする。<br> <br> 次に、この変更をmasterブランチに取り込む。<br> masterブランチにチェックアウトして、<code>git merge --no-ff <ブランチ名 例: topic></code>コマンドを使用する。<br> <u>必ず、<code>--no-ff</code>オプションを付加すること。</u><br> <br> この時、topicブランチのコミットログがmasterブランチ側に残らないように配慮する必要がある。<br> <code>--no-ff</code>オプションにより、fast forwardを行わない独立したコミットが作成される。<br> <br> masterブランチのコミットログを見ると、基本的には直列の履歴かつ変更コミットが機能ごと (topicブランチごと) に独立して見える。<br> <br> # --no-ffオプションにより、マージコミットが明示的に作成される。 # topicブランチの変更が1つのまとまりとしてmainブランチに統合される。 # mainブランチの履歴が直線的に保たれる。 [[ファイル:Git Merge Rebase 4.png|フレームなし|中央]] <center>図. 最終的なmerge (--no-ff) 後の状態</center><br> <br><br> == 備考 == masterブランチを進める観点で見ても、作成される履歴に違いが出る。<br> <br> 一般的には、どのような履歴を残すかによって使い分けるが、masterブランチなどの統合ブランチの履歴をシンプルに保つ等の目的で、<br> 以下のような方針で運営するケースもよく見られる。<br> <br> masterブランチ等の統合用ブランチに、別ブランチをmerge(または、pull request)する前に、必ず最新のmasterブランチでrebaseしてからmerge(または、pull request)する。<br> これらは、チームの運営方針に合わせる。<br> <br><br> __FORCETOC__ [[カテゴリ:Git]]
Gitの基礎 - rebaseとmergeの使い分け
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse