1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今さら学ぶgitの超基礎

Last updated at Posted at 2025-02-26

gitはfetch, add, commit, pushだけ知ってれば大丈夫

これは私が新卒時代に「Git は何を勉強すればいいですか?」と先輩に聞いたときの言葉です。
実際、プロジェクトのブランチ運用ルールが確立され、適切に守られているのであれば、この言葉の通りかもしれません。

しかし、ブランチルールから逸脱した操作 が発生すると、コミット履歴を追跡し、原因を特定して対応しなければならなくなります。そのためには、Git の仕組みを理解しておく必要があります。

この記事では、「Git のブランチの正体」と「2つのマージ方法」 について解説し、私自身の理解を深めるためにまとめました。

ブランチの正体

git commit を実行すると、Git は「コミットオブジェクト」と呼ばれるデータを作成します。
このコミットオブジェクトには、以下の情報が含まれています。

  • コミットの内容(変更履歴)
  • 親コミット(修正)へのポインタ
  • コミットメッセージ

ブランチの正体は、最新のコミットを指すポインタです。

例えば、以下のようなコミット履歴があるとします:

A - B - C  (main)

ここで main ブランチは Cのコミットを指しているポインタ です。
そして、今どのブランチを見ているかを指すポインタがHEADと呼ばれるものです。例えばmainブランチからfeatureブランチを作成し、featureブランチに切り替えたとします。そうするとHEADmainからfeatureに移動します。

A - B - C  (main)
         \
          (feature, HEAD)

以降の説明では HEAD は省略しますが、ブランチを移動すると HEAD も移動している ということを意識してください。

2つのマージ方法

ブランチの仕組みが分かったところで、マージ方法について説明します。Gitのマージには、以下の2種類があります。

  • Fast-forward マージ
  • Three-way マージ

この違いを説明するために、以下のブランチを使います。

  • main ブランチ(基準となるブランチ)
  • feature/1 ブランチ(main から分岐)
  • feature/2 ブランチ(main から分岐)

Gitのブランチは最新のコミットを指すポインタなので、作成直後の3つのブランチは同じコミットを指している状態です。以下の図では、各ブランチが指すコミットを箱(コミットハッシュ)で表しています。

スクリーンショット 2025-02-26 12.47.10.png

以降の説明はこの状態からスタートします。

fast-forward

今mainブランチにいるとして、feature/1ブランチに移ります。そしてそこでtext_1.txtを追加するという変更を行い、それをcommitします。するとコミット履歴とブランチの状態は以下のようになります。

スクリーンショット 2025-02-26 13.14.01.png

この状態でmainfeature/1をマージすると、Gitは次の3つの情報を確認します。

対象 ブランチ名 コミットハッシュ
マージ元 feature/1 032fe65
マージ先 main 7e2afb5
マージ元/先の共通先祖 main 7e2afb5

この状態をみると、マージ先であるmainの最新コミットがfeature/1との共通の祖先のコミットと一致しているため、単純にポインタをfeature/1に進めるだけでOKです。

マージ元/先の共通の先祖はgitが自動的に判別してくれています

% git merge feature/1
Updating 7c2afb5..032fe65
Fast-forward
 text_1.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

このように、ポインタを進めるだけのマージをFast-forwardマージと呼びます。

スクリーンショット 2025-02-26 13.14.29.png

three-way-merge

次にfeature/2ブランチに移り、text_2.txtというファイルを追加する変更を行います。するとコミット履歴とブランチの状態は以下のようになります。

スクリーンショット 2025-02-26 13.17.19.png

この状態でfeature/2をmainブランチにマージします。今回のケースではマージ元/先、共通の先祖は以下のようになっています。

ブランチ種別 ブランチ名 コミットハッシュ
マージ元 feature/2 9512fe5
マージ先 main 032fe65
マージ元/先の共通先祖 main 7e2afb5

先ほどのfast-forwardと違ってすべてコミットハッシュがバラバラになっています。この状態でmainブランチに移りfeature/2をマージするとどうなるでしょう?

% git merge feature/2
Merge made by the 'ort' strategy.
 text_2.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 text_2.txt

このように無事マージはできましたが、fast-forwardの文字が表示されていません。これは、今回のようなパターンではthree-way-mergeと呼ばれる方法でマージが行われたからです。

スクリーンショット 2025-02-26 13.23.40.png

Gitは共通の祖先7e2afb5を基にmain032fe65feature/29512fe5を統合し、新しいマージコミットa899daeを作成します。
「共通の祖先」をもとに 3 つのコミットを比較して統合するのがThree-way Mergeと呼ばれるマージ方法になります。おそらく案件などでよく見かけるのはこちらのパターンになると思います。

まとめ

gitブランチの正体とマージのパターンについてまとめました。時々必要に駆られてrevertresetの操作をするのですが、仕組みがよくわからかったのがこのgitの基本を知ってからようやく意味がわかるようになりました。gitの公式ドキュメントがかなり優しく詳しい解説をしているので一度読んでみるのをおすすめします。

参考記事

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?