LoginSignup
30
28

More than 3 years have passed since last update.

初心者がしっかりと理解できるようにGitのブランチを説明する

Last updated at Posted at 2020-12-08

前回はリモートリポジトリにローカルリポジトリの内容をpushするところまでを解説しました。
今回はいよいよ、ブランチについて解説していきます!

前回までの知識がある前提で話を進めますので、まだこれらを読んでない方は是非読んでください。

なぜ僕らはGitでバージョン管理をするのか
Gitを触り始めてからGitHubにpushするまでの流れを誰よりも丁寧に説明する

ここではコミットログの解説をするためにターミナルでログを出力します。めっちゃ見辛いログです。
最後にログを見やすくするためのツールを紹介するので、それまでは耐えてください。

ブランチとは?

ブランチという機能、Gitを触りたての頃は何が何だかよくわからないと思います。
端的に言うと「コミット(セーブポイント)の分岐を作る」機能です。その分岐を「ブランチ」と呼んでいます。
これにより、ブランチAでは機能Aの開発をしブランチBでは機能Bの開発をする、という住み分けが可能になります!

何が嬉しいのかは、これから詳しく説明する中で理解できると思います。

Gitはコミットの履歴を管理している

コミットは上書きされるものでなく、追加されるものです。
その追加の履歴をGitで管理しています。
ブランチを理解するにはまずこの概念を理解する必要があります!!

順に確認していきましょう!

コミットログを確認しよう

空のローカルリポジトリを新しく作ってください。(参考
そしてファイルを作成し、コミットしてみましょう。

$ mkdir (フォルダ名) // フォルダを新規作成する
$ cd (フォルダ名)    // カレントディレクトリを移動する
$ git init         // カレントディレクトリをGit管理する
$ touch test       // 'test'というファイルを新規作成する
$ git add test     // 'test'をステージする
$ git commit -m 'add test'  // 'add test'というコミットメッセージでコミットする

次に、コミットのログを確認してみましょう!そのコマンドはgit logです。

$ git log

commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563 (HEAD -> master)
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:21:59 2020 +0900

    add test

なんか出てきましたね。これがコミットログ(コミットの履歴)です。

読み方を少し解説します。

コミットにはハッシュと言うものが割り当てられ、ハッシュとコミットは1対1で対応しています。ハッシュでコミットを識別します。先頭7桁で識別できるようです。今回特に重要ではないので、詳しくはググってください。
ログにはそのハッシュと、コミットしたユーザー名・コミットした時間・コミットメッセージが表示されています。

コミットログの説明
commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563 (HEAD -> master) // ()内は後ほど解説します
// 33b53a587aa2d1f4a79d126de8d717e4bd97d563 がハッシュ(先頭の33b53a5だけで識別可能)

Author: gakisan8273  // コミットしたユーザー
Date:   Tue Dec 8 01:21:59 2020 +0900 // コミットした時間

    add test // コミットメッセージ

今は1回のみコミットをしたので、1コミットだけがログに表示されています。
それではtest2ファイルを新規作成しコミットして、ログを見てみましょう!

$ touch test2
$ git add test2
$ git commit -m 'add test2'
$ git log

commit d4de11a70e45c9d7c4481fd3b1aa1d10445d839b (HEAD -> master)
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:31:13 2020 +0900

    add test2

commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:21:59 2020 +0900

    add test

ログが増えました!やったね!
最初のコミットは消えていません。コミットは上書きでなく追加されることが分かったかと思います。

コミット時間を見ればわかるように、新しいコミットが上に表示されています。

ここでハッシュの行だけを抜き出して表示してみます。

ログから抜粋
commit d4de11a70e45c9d7c4481fd3b1aa1d10445d839b (HEAD -> master) // (HEAD -> master)の位置が移動している!
commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563  // d4de11aをコミットする前はここに(HEAD -> master)があった

d4de11aのコミットをしたら、(HEAD -> master)33b53a5からd4de11aに移動してます!!

何が起こっているのでしょう?

HEADは最新のコミットを指す

まずHEADから説明しましょう。これは単純に最新のコミットを指しています。
最初のコミットの時点では、当然それが最新のコミットでした。なのでHEADがそれにあたります。
次にtest2を追加するコミットをしたら、最新のコミットは変わりますよね。
なのでログのHEADの位置も移動しています。

次にコミットするとき、33b53a5d4de11aの間にコミットを追加することはできません。
なぜならば、d4de11aのコミットをした時点で、作業をする場所が最新のd4de11aに移動しているからです。
コミットをすると履歴が追加され、常に最新のコミットを参照することを覚えておいてください。

(HEAD -> master)HEADは何となく分かったかと思います。じゃあ-> masterって何よ?に答えていきましょう!

コミットログはブランチごとに存在する

ようやく出ました、ブランチという言葉。
ここまでの作業でブランチを作った記憶はありませんよね。しかし、Gitはデフォルトでmasterというブランチを1つだけ作っています。
これがいわゆるブランチの「本流」になります。

ローカルリポジトリにどんなブランチがあるかをgit branchコマンドで確認しましょう。

$ git branch

* master // これがブランチ名 先頭の*は作業ブランチであることを示す

このように表示されましたね?現在はmasterブランチ1つだけがあることが確認できました。
Gitの場合、必ず「作業ブランチ」というものを指定します。その作業ブランチに対してコミットを実行しているのです。
ブランチ名の先頭に*がついているのは、それが作業ブランチであることを示しています。
今はブランチが一つしかないので、自動的にmasterが作業ブランチになっています。

実は、HEADが指しているブランチが作業ブランチになるのです。

(HEAD -> master)HEADmasterを指しているので、

  • 作業ブランチはmasterである

ということを表しています!!!!

ブランチを作成してみよう(切ってみよう)

他のブランチがあるとどうなるか、確認してみましょう。
ブランチを作成することを、ブランチを切るといいます。何ででしょうね?

ブランチを切るコマンドは、git branch (ブランチ名)です。
new_branchという名前のブランチを切ってみましょう。

$ git branch new_branch
$ git branch

* master      // 作業ブランチはmasterのまま
  new_branch  // ブランチが作成された!!

この状態でログを見てみると…

$ git log

commit d4de11a70e45c9d7c4481fd3b1aa1d10445d839b (HEAD -> master, new_branch) // new_branchが追加された!!!!
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:31:13 2020 +0900

    add test2

commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:21:59 2020 +0900

    add test

d4de11anew_branchが追加されました!!
(HEAD -> master, new_branch)の意味を解説しましょう!

作業ブランチはmaster(HEADが指しているから)ですね。そして同じコミットにnew_branchもいるようです。
今はmasternew_branchが同じコミットを指している同じ状態であると言えます。

ここでコミットを追加すると違いが見えてきます。

ブランチを切った上でコミットしてみよう

今の作業ブランチはmasterのままです。
add_masterファイルを追加してコミットしてみましょう。

$ touch add_master
$ git add add_master
$ git commit -m 'add_master'
$ git log

commit debb8c883b12488593aed009d897300dc21f70d9 (HEAD -> master) // masterだけコミットが追加された
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 02:08:51 2020 +0900

    add_master

commit d4de11a70e45c9d7c4481fd3b1aa1d10445d839b (new_branch) // new_branchは変わってない
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:31:13 2020 +0900

    add test2

commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:21:59 2020 +0900

    add test

お分かりいただけただろうか。
作業ブランチであるmasterはコミットが追加されたが、new_branchはそのままです。

もう少し分かりやすくするため、次は作業ブランチをnew_branchに切り替えてコミットしてみましょう。

作業ブランチを切り替えてみよう

切り替えるコマンドはgit checkout (ブランチ名)です。
そしてadd_new_branchファイルを追加してコミットしてみましょう。

$ git checkout new_branch // 作業ブランチが切り替わる
$ git branch

  master
* new_branch // 作業ブランチが切り替わっている
$ touch add_new_branch
$ git add add_new_branch
$ git commit -m 'add_new_branch'
$ git log

commit 7df16ad90a5112d27bfa3d0e9487fb82591007e4 (HEAD -> new_branch) // d4de11aに追加されたコミット
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 02:14:26 2020 +0900

    add_new_branch

commit d4de11a70e45c9d7c4481fd3b1aa1d10445d839b // さっきまでnew_branchがいたコミット
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:31:13 2020 +0900

    add test2

commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563
Author: gakisan8273 <mint.daa.a2@gmail.com>
Date:   Tue Dec 8 01:21:59 2020 +0900

    add test

d4de11a7df16adが追加されたことが分かります。
masterが見当たりませんね?git logだけでは作業ブランチに関するログしか表示してくれません。

コマンドにオプションを足してみましょう。git log --graph --allを実行してください。
--graphはログをグラフで表示するオプション、--allは全てのブランチを表示するオプションです。

$ git log --graph --all // --graph グラフ表示する  --all 

* commit 7df16ad90a5112d27bfa3d0e9487fb82591007e4 (HEAD -> new_branch)
| Author: gakisan8273 <mint.daa.a2@gmail.com>
| Date:   Tue Dec 8 02:14:26 2020 +0900
|
|     add_new_branch
|
| * commit debb8c883b12488593aed009d897300dc21f70d9 (master)
|/  Author: gakisan8273 <mint.daa.a2@gmail.com>
|   Date:   Tue Dec 8 02:08:51 2020 +0900
|
|       add_master
|
* commit d4de11a70e45c9d7c4481fd3b1aa1d10445d839b  // このコミットからブランチが分かれている!!
| Author: gakisan8273 <mint.daa.a2@gmail.com>
| Date:   Tue Dec 8 01:31:13 2020 +0900
|
|     add test2
|
* commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563
  Author: gakisan8273 <mint.daa.a2@gmail.com>
  Date:   Tue Dec 8 01:21:59 2020 +0900

      add test

左の縦線・斜め線がコミットの流れを表しています。雰囲気を感じ取ってください。

d4de11aを起点にして、masternew_branchが分かれていますね!!!
このように木の枝のように分かれるためbranchと呼ばれています。

debb8c8masterだけが持つコミット
7df16adnew_branchだけが持つコミット であることが伺えます。

つまり、ブランチごとにコミットログが存在するということです!

また、HEADmasterからnew_branchに移っていることが分かります。
作業ブランチを切り替えることは、HEADの位置を切り替えることと同じです。

今はadd_masterファイルはmasterブランチだけが参照でき、add_new_branchファイルはnew_branchブランチだけが参照できることになります。
確認してみましょう。

new_branchが作業ブランチ
$ git branch

  master
* new_branch

$ ls // カレントディレクトリに存在するファイルを表示するコマンド

add_new_branch test           test2 // add_masterはない
masterに作業ブランチを切り替える
$ git checkout master
$ git branch

* master
  new_branch

$ ls

add_master test       test2  // add_new_branchはない

それぞれの作業ブランチでコミットしたものしかないことが分かります。

ブランチを統合しよう

実際にシステムを運用するときは本流であるmasterブランチを参照するでしょう。
new_branchで追加したadd_new_branchファイルをmasterに反映させる必要があります。

そのコマンドが、git merge!!!!
実行してみましょう!!

$ git branch

* master               // masterにブランチを統合したいので、作業ブランチをmasterにする
  new_branch

$ git merge new_branch // 作業ブランチに統合するブランチを指定する

mergeすると、このようにコミットメッセージを入力するためにvimが起動します。
コミットメッセージを変更せずに、:qを入力してエディタを閉じましょう。

merge後にコミットメッセージを入力する
  1 Merge branch 'new_branch'  // ここがコミットメッセージ
  2 # Please enter a commit message to explain why this merge is necessary,
  3 # especially if it merges an updated upstream into a topic branch.
  4 #
  5 # Lines starting with '#' will be ignored, and an empty message aborts
  6 # the commit.
~

これでmasternew_branchが統合されました。このことをマージと呼びます。
masterに何のファイルがあるか見てみましょう。

$ git branch

* master
  new_branch

$ ls

add_master     add_new_branch test           test2  // add_master, add_new_branch 両方ある!!

masterで追加したadd_masternew_branchで追加したadd_new_branchの両方がmasterにあることが確認できます!
ブランチがマージ(統合)された、ということですね。

コミットログを見てみましょう。

$ git log --graph --all

*   commit 4010613273f3d1539a346f34562730e4510e9704 (HEAD -> master)
|\  Merge: debb8c8 7df16ad
| | Author: gakisan8273 <mint.daa.a2@gmail.com>
| | Date:   Tue Dec 8 12:14:33 2020 +0900
| |
| |     Merge branch 'new_branch'
| |
| * commit 7df16ad90a5112d27bfa3d0e9487fb82591007e4 (new_branch)
| | Author: gakisan8273 <mint.daa.a2@gmail.com>
| | Date:   Tue Dec 8 02:14:26 2020 +0900
| |
| |     add_new_branch
| |
* | commit debb8c883b12488593aed009d897300dc21f70d9
|/  Author: gakisan8273 <mint.daa.a2@gmail.com>
|   Date:   Tue Dec 8 02:08:51 2020 +0900
|
|       add_master
|
* commit d4de11a70e45c9d7c4481fd3b1aa1d10445d839b
| Author: gakisan8273 <mint.daa.a2@gmail.com>
| Date:   Tue Dec 8 01:31:13 2020 +0900
|
|     add test2
|
* commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563
  Author: gakisan8273 <mint.daa.a2@gmail.com>
  Date:   Tue Dec 8 01:21:59 2020 +0900

      add test

masterでマージをしたので、マージコミットというものが最新のコミット(4010613)として生まれます。
左の縦線が7df16ad(new_branchが参照してるコミット)から4010613(masterの最新コミット)に伸び、統合されています。

・・・だから何?なんでブランチが必要なの?masterだけで作業すればマージする必要もなくていいじゃん!

と、思いますよね。ブランチがあると何が嬉しいのかを説明していきましょう!

ブランチの嬉しさ

ブランチにより別機能開発を同時並行しやすくなります!!!!

ブランチがmaster一つしかない場合を想像してください。


あなたはmasterブランチで機能Aの開発をしています。いい感じに実装を進めていると上司から「急ぎで機能Bを実装してくれ!」と依頼が来ました。
機能Aの実装を中断するため、キリのいいところでコミットしました。機能Aは少しバグがあるものの、動いています。
そして機能Bの実装を開始します。

機能Bの実装を無事終えてユーザーが使用を始めています。機能Aの実装に戻ることにしました。
ところが!機能Aが全く動作しなくなっていました!!!原因は機能Bの実装であることは明らかです。
修正するには機能Bで実装したところに手を入れるしかありません。
しかしそれをすると、今ユーザーが使っている機能Bが動かなくなってしまうかもしれません…困った…どうしよう…


機能ごとにブランチを分けた場合を考えてみましょう。


あなたは機能Aの開発をするため、masterブランチからfunction_aブランチを切り、そこで実装を進めていました。
上司から「急ぎで機能Bを実装してくれ!」と依頼が来ました。
機能Aの実装を中断するため、function_aブランチでキリのいいところでコミットしました。機能Aは少しバグがあるものの、動いています。
そして機能Bの実装を開始するため、masterブランチからfunction_bブランチを切りました。

機能Bの実装を無事終えて、function_bmasterブランチにマージしました。ユーザーが使用を始めています。
機能Aの実装に戻るため、function_aブランチに切り替えます。
function_afunction_bは互いに独立しているので、機能Aは中断した時と変わりありません。
そのままfunction_aブランチで機能Aの実装を終え、masterにマージして無事リリースできました。


どうでしょう。嬉しさが少しは分かったのではないでしょうか?

とはいえ…ブランチは実際に開発で使わなければその恩恵が理解しにくいと思います!!!!
また一人で開発している分にはブランチを切らなくてもあまり不自由ありません!!!!(個人差があります)

しかしぜひ!!ブランチを使ってみて何ができるかを体感して欲しい!!!お願いします!!

コミットログって見にくくない???

さて皆さん、ここまでコミットログをターミナルで表示して来たかと思います。
クッソ見辛いですよね???だから解説もしにくいし…

もっと見やすくする方法があるので、それを紹介します。

VSCodeの拡張機能「Git Graph」を使おう!!!

まずVSCodeというエディタをインストールしてください。方法はググってください。
そしたらVSCodeを起動し、VSCode内の拡張機能でgit graphと検索します。出ます。
インストールしましょう。

スクリーンショット 2020-12-08 14.26.47.png

ソース管理タブのGitGraphっぽい右側のアイコンをクリックすると、ウィンドウにコミットログが表示されます。

スクリーンショット 2020-12-08 14.29.12.png

この見やすさの違い、Git Graphを使わない理由がない!
Git Graphでもハッシュやコミットメッセージが見れるのは当然で、それに加えてコミット内容などまで見ることができます。
ターミナルの上位互換と考えて差し支えないです。

$ git log --graph --all

*   commit 4010613273f3d1539a346f34562730e4510e9704 (HEAD -> master)
|\  Merge: debb8c8 7df16ad
| | Author: gakisan8273 <mint.daa.a2@gmail.com>
| | Date:   Tue Dec 8 12:14:33 2020 +0900
| |
| |     Merge branch 'new_branch'
| |
| * commit 7df16ad90a5112d27bfa3d0e9487fb82591007e4 (new_branch)
| | Author: gakisan8273 <mint.daa.a2@gmail.com>
| | Date:   Tue Dec 8 02:14:26 2020 +0900
| |
| |     add_new_branch
| |
* | commit debb8c883b12488593aed009d897300dc21f70d9
|/  Author: gakisan8273 <mint.daa.a2@gmail.com>
|   Date:   Tue Dec 8 02:08:51 2020 +0900
|
|       add_master
|
* commit d4de11a70e45c9d7c4481fd3b1aa1d10445d839b
| Author: gakisan8273 <mint.daa.a2@gmail.com>
| Date:   Tue Dec 8 01:31:13 2020 +0900
|
|     add test2
|
* commit 33b53a587aa2d1f4a79d126de8d717e4bd97d563
  Author: gakisan8273 <mint.daa.a2@gmail.com>
  Date:   Tue Dec 8 01:21:59 2020 +0900

      add test

スクリーンショット 2020-12-08 14.29.56.png

便利ツールの落とし穴

Git Graphは様々な機能を持っています。
マウスポチーでコミットの取り消しができたり、コミットの移動ができたりもします。
しかし!これを読んでいる皆さんはまだその機能を使わないでください!!

結局はどんな操作でも裏でGit Graphがコマンドを叩いているので、「この操作でどんなコマンドが実行されるのか」を理解していないと思わぬ事故に繋がります。

まずターミナルでどう操作すればいいかを理解してから、便利なツールを使いましょう!
本記事でクッソ見辛いgit logをあえて使ったものその理由からです。

さいごに

ブランチの説明、プログラミング初学者に分かりやすく説明するのはめっちゃ難しいです。
僕も学びはじめの頃、色々な解説記事を見ましたが何が何だか分かりませんでした…
しかし、実際にブランチを切って触っていくうちに理解できました。

例によってこの記事は初学者向けに書いているので、正確でない部分もあります。
しかし最初はこの理解で十分ですので、気になったらその都度精査してみてください。

この記事がしっかりと解説してくれているので、より細かく知りたい方は是非参照してみてください。
図解! Gitのブランチ・ツリーをちゃんと読む

特にこのブランチという機能は実際に触らなければ、そして複数人開発をしなければ、必要性が分かりにくいものだと思います。
初学者にとっては非常にとっつきにくいものでしょう。

とりあえず何か開発するときは、機能ごとにブランチを切る習慣をつけておいて欲しい!
そうしてればそのうちコンフリクトが起こって解消方法に悩んだり、rebaseしたりcherry-pickしたくなる時が来るでしょう。
それらを一つ一つ乗り越えて徐々に理解が深まっていくものです。

さあ自分のリポジトリにブランチを作ってみよう!!!

よかったらTwitterもフォローしてね。怪しいアカウントじゃないよ。

30
28
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
30
28