ブランチを使うと、同じプロジェクトで複数の作業を互いに邪魔せず並行して進められます。この記事では、ブランチとは何か、なぜ必要なのかを確認し、作成や切り替え、変更のマージ、そしてIDEのツールを使って落ち着いてコンフリクトを解決する方法を学びます。Claude Codeが別ブランチでリポジトリを操作するときの動きを理解するために、押さえておきたい基礎です。

例と画面キャプチャはJetBrains IDEのものです。操作名や配置はお使いのバージョンによって異なる場合があります。演習には専用の学習用リポジトリを使ってください。実際のプロジェクトでは、そのプロジェクトのブランチ、コミット、変更の送信に関するルールに従いましょう。

ブランチとは何か、なぜ必要なのか

ブランチは、個別のコミット系列につける名前です。ブランチを作成しても、プロジェクトのフォルダーがコピーされたり、未コミットのファイルが保存されたりするわけではありません。通常の作業フォルダーでは、ブランチを切り替えるとGitが選択したブランチに合わせてファイルを更新します。未完了の変更は切り替え先にも引き継がれることがあり、切り替えを妨げる場合もあります。

上の線はmain、下の線はfeature/new-ideaです。マージ後、mainは2つの親EとDを持つMを指します。ABEMCD
上の線はmain、下の線はfeature/new-ideaです。マージ後、mainは2つの親EとDを持つMを指します。

メインブランチのmainから、個別に開発を進めるための新しいブランチfeature/new-ideaが分かれます。作業が終わったら、変更をmainにマージします。

プロジェクトを大きく作り変えたり、リスクのある実験をしたりしたいとします。Gitがなければどうするでしょうか。おそらくプロジェクト全体を別のフォルダーにコピーして、そこで作業するでしょう。結果が気に入れば、メインのフォルダーに反映します。そうでなければ、そのコピーを削除するだけです。

コピーのたとえは別々の作業をイメージするのに役立ちますが、技術的にはブランチはコミットを指すポインターです。本にたとえてみましょう。

  1. 完成した原稿があります(これがメインブランチのmainです)。
  2. 別の結末を書きたいので、新しいブランチ(たとえばfeature/new-idea)を作成します。
  3. 原稿の本文には手を加えず、新しい結末を書きます(新しいブランチで作業します)。
  4. 新しい結末のほうがよければ、古い結末と置き換えます(ブランチをmergeします)。
  5. 不要になった結末の古い下書きは削除できます(ブランチを削除します)。
Claude Codeとの連携

まずClaude Codeにブランチと既存の変更を表示するよう頼んでください。プロジェクトのルールに合う場合は、別のブランチを作成します。保存済みのコミットは復帰地点になります。ブランチ名を削除しても、それだけでファイルの変更が取り消されたり、元の状態に戻ったりはしません。

新しいブランチを作成して作業する

手順1. ブランチ管理メニューを開きます。

メインツールバーのプロジェクト名の横に、現在のブランチ名を表示するウィジェットがあります(デフォルトはmain)。それをクリックし、+ New Branchを選択します。

左上にあるブランチウィジェット

手順2. 新しいブランチに名前を付けます。

ブランチ名は、取り組んでいる作業に合わせて付けるのがおすすめです。たとえばfeature/add-usage-examplesのようにします。

新しいブランチの作成ウィンドウ

作成時にCheckout branchを選択すると、IDEは新しいブランチに切り替わります。ファイルを編集する前に、ウィジェットでブランチ名を確認してください。

手順3. 変更を加えてコミットします。

README.mdに使用例のセクションを追加します。変更内容を確認し、いつもの方法でcommitしてください。新しいブランチの履歴に、その時点のスナップショットが記録されます。

新しいブランチでのコミット
Claude Codeとの連携

Claude Codeがcommitを提案するとき、行うのはまさにそれです。現在の変更を、あとで戻れる地点として記録します。承認する前にコミットメッセージを読んでください。メッセージには何が変わるのかが書かれていて、簡単に修正できます。

ブランチを切り替える

使用例の変更はfeature/add-usage-examplesブランチに安全に保存されました。メインブランチのmainに戻って、そちらを見てみましょう。

手順1. 左上にある現在のブランチ名のウィジェットをもう一度クリックします。

手順2. LocalまたはRecentの一覧からmainブランチを選び、表示されたサブメニューでCheckoutをクリックします。

mainブランチへの切り替え

手順3. 結果を確認します。

切り替えたら、README.mdを開いてください。使用例のセクションがないことに気づくはずです。変更は別のブランチに残っています。このように、mainブランチの安定版に影響を与えず、新しい機能に取り組めます。

別ブランチの変更が反映されていないファイル

ブランチをマージする

mergeは、選択したブランチの履歴を現在のブランチに統合します。分岐後にmainが進んでいなければ、fast-forwardが可能です。この場合、新しいコミットを作らずにmainがC3へ移動します。履歴が分岐していれば、通常のマージで2つの親を持つコミットが作成されます。

新しいコミットを作らずにmainがC2からC3へ移動しますC1C2C3
新しいコミットを作らずにmainがC2からC3へ移動します

図のように履歴が一直線の場合、mainはC3へ移動できます。feature/add-usage-examplesブランチもまだC3を指しています。マージのためにブランチ名を削除する必要はありません。

feature/add-usage-examplesブランチでの作業が終わり、その変更をメインのプロジェクトに加えたいとします。

手順1. マージ先のブランチに切り替えます。

変更の追加先になるブランチにいることを確認してください。この例ではmainです。

手順2. マージを実行します。

ブランチ管理ウィジェットをもう一度クリックします。一覧から、変更の取り込み元になるブランチ(feature/add-usage-examples)を選びます。サブメニューでMerge 'feature/add-usage-examples' into 'main'を選択します。

ブランチのマージを実行

手順3. 結果を確認します。

mainブランチのREADME.mdに、新しい使用例のセクションが追加されました。作業内容をプロジェクトのメイン版にマージできました。

マージ完了

マージコンフリクト

コンフリクトは、Gitが変更を自動で統合できなかったことを意味します。よくあるのは、同じ行に異なる変更があるケースです。一方のブランチでファイルを削除し、もう一方で変更した場合にも起こります。どのように解決するかは、求める結果に応じて決めます。

ここではIDE(CLionまたはIntelliJ IDEA)に組み込まれたツールが役立ちます。ターミナルでコンフリクトを解決するのはなかなか大変ですが、内蔵の3-way mergeツールを使えば、状況を見ながら簡単に解決できます。

共通の祖先C1から分岐した2つのブランチC1C2C3
共通の祖先C1から分岐した2つのブランチ

どちらのブランチにも、共通の祖先C1からコミットが追加されています。履歴が分岐しただけでコンフリクトが起きるわけではありません。Gitが変更を自動で統合できない場合に発生します。次の演習では、ひとつの元の行を異なる文で置き換えます。

コンフリクトを再現してみましょう。

  1. mainブランチにいることを確認し、Commitウィンドウに未コミットの変更や新しいファイルがないことを確認します。
  2. 新しいブランチfeature/new-titleを作成しますが、まだ切り替えないでください。Checkout branchのチェックが外れていることを確認します。
  3. mainブランチにいる状態で、README.mdの1行目を"素晴らしいプロジェクト"に変更し、commitします。
  4. feature/new-titleブランチに切り替えます。README.mdの1行目は古いままです。ブランチを作成した時点のファイルだからです。同じ行を"最高のプロジェクト"に変更し、commitします。
  5. mainブランチに戻り、feature/new-titleをマージします。

これでGitは、両方の履歴の同じ箇所が変更されたことを検出します。コンフリクト解決用のウィンドウ(Merge Conflicts)が表示されます。

コンフリクト検出ウィンドウ

Mergeボタンをクリックして、コンフリクト解決ツールを開きます。ここには次の内容が表示されます。

  • 左側(Your changes)は現在のブランチ、つまりマージ先のmainにあるファイルです。
  • 右側(Changes from branch)は、マージするブランチにあるファイルです。
  • 中央(Result)は最終的なファイルです。ここで手作業で内容を組み立てます。
3方向コンフリクト解決ウィンドウ

>>または<<の矢印をクリックすると、どちらかの変更をそのまま採用できます。取り消す場合は×印をクリックします。中央のパネルに正しい内容を直接入力することもできます。

中央のパネルで結果を確認し、Applyまたは該当する完了ボタンをクリックします。その後、Gitの状態を確認してください。マージがまだ記録されていなければ、IDEでコミットします。コンフリクト行の解決とmergeの完了は別の手順です。できあがったコードの動作も確認しましょう。

Claude Codeとの連携

Claude Codeの作業中にコンフリクトが起きても、障害ではありません。Claudeは作業を止めて助けを求めたり、変更を分ける方法を提案したりすることがあります。通常のコンフリクトと同じく、IDEの3-way mergeツールで解決できます。

コンフリクトが起きないことがある理由

演習でコンフリクトが起きなかった場合は、2つ目のブランチがどのコミットから作られたか、両方のブランチで同じ行を異なる内容に置き換えたかを確認してください。履歴が分岐していても、互換性のある変更ならGitは自動で統合できます。もうひとつは、fast-forwardが可能な一直線の履歴です。

例:

  1. mainに何かのコミットがあるとします(仮にC1)。
  2. mainブランチに"素晴らしいプロジェクト"という内容の新しいコミットを作ります。ブランチmainはコミットC2を指すようになります。
  3. 現在のmainの位置からfeature/new-titleブランチを作ります。新しいブランチもコミットC2から始まります。
  4. feature/new-titleに"最高のプロジェクト"という内容のコミットを作ります。このブランチは先へ進み、コミットC3を指します。
  5. コミットC2を指したままのmainに戻り、feature/new-titleをマージします。

別のブランチで作業している間、mainには新しいコミットがありません。そのためGitは、mainがfeature/new-titleの直接の祖先だと判断します。コンフリクトなしで、mainのポインターをコミットC3まで進めます。

新しいコミットを作らずにmainがC2からC3へ移動しますC1C2C3
新しいコミットを作らずにmainがC2からC3へ移動します

mainの履歴はfeature/new-titleの履歴に分岐せず続いています。そのためGitはmainをそのまま先へ進めます。コンフリクトは起きません。

変更履歴を確認する

プロジェクトで何が起きているかをよりよく把握するには、履歴を確認すると役立ちます。

Gitツールウィンドウを開きます(通常は左側のサイドバーかIDEウィンドウの下部にあるアイコンです)。GitツールバーでLogまたはShow Git Logタブを選択します。ブランチとコミットのグラフが表示されます。どのブランチがどこから分岐し、どこでマージされたのかを確認できます。

Gitログウィンドウ

ここでは任意のコミットをクリックして、含まれる変更や、誰がいつ作成したのかを確認できます。コードのためのタイムマシンのようなものです。

Claude Codeとの連携

Claude Codeの変更は、通常のコミットとして記録されるとこの履歴に加わります。Git Logでは自分の変更と同じように確認できます。コミットを開いて、具体的に何が変わったのかを見てみましょう。

Claude Codeとブランチの連携

ブランチを理解すると、Claude Codeがリポジトリで作業するときの動きも読み取りやすくなります。この仕組みを使ってClaude Codeが行うことと、確認しておきたい点を見ていきましょう。

  • 作業内容とプロジェクトのルールに合う場合は、別のブランチを作成します。
  • 要所でcommitを提案します。diffを読んで、承認するか修正するかを判断してください。
  • 保存済みのコミットを探し、未コミットの変更を考慮して戻し方を選ぶのを手伝います。
  • マージコンフリクトが起きたら、助けを求めることがあります。解決には同じIDEツールを使います。
  • たとえばGitHub CLIを使って、pull request(PR。ブランチをメインブランチにマージする提案)を作成し、コメントできます。
Claude Codeとの連携

承認する前にdiffを確認してください。特に、Claudeがファイルの削除やmergeを提案したときは重要です。そうすれば、プロジェクトの履歴に何が記録されるのか把握できます。

前の記事:Gitを使った日々の作業 · 次の記事:Pull requestの作成からマージまで