この記事の内容は git でブランチを扱う話で、シンプルな事例となるものです。
今回の題材
今回の題材は、ヌーラボさんの Git関連のページにある事例を使ってみます(※ これを元に、少し内容を変えたものを準備しm)。
試す内容の元になるもの
元にする事例は、具体的には以下の部分に書かれたものです。
これを少しだけ変えたものを 2つ、試してみることにします。
少しだけ流れに手を加える
上記の題材を元に、少しだけ手を加えた流れを 2つ用意して、それぞれをやってみようと思います。
この後、Mermaid を使った Qiita のコードブロックで、gitGraph を描画したもので流れを示します。
試す内容の 1つ目
試す内容の 1つ目は以下です。
main と bugfixブランチでそれぞれ変更を加え、bugfixブランチで加えた変更を main にマージするというものです。
まずはブランチの利用で、最小限の手順にした流れをテスト的に試してみる、という意図のものです。
試す内容の 2つ目はまた後で示します。
1つめの内容を試す
それでは、上で示した内容を実際に試していきます。
前提条件
今回の目的は、ブランチを使う操作を試すことを想定しています。
そのため、元になるリポジトリはテスト用にローカルに作ったもので進めます。
実際の内容
それでは、実際に試していきます。
ベースを準備する
まずは以下のコマンドで、ベースとなる内容を準備します。
git init
echo "# ブランチのテスト用のリポジトリ" > README.md
git add README.md
git commit -m "A:最初の状態"
ブランチを作成してコミット
ここからブランチを作成して、以下の状態にしてみます。
具体的なコマンドは以下です(一部、エディタでのファイル編集)。
git switch -c bugfix
git branch
【※ この部分でエディタで「README.md」を編集】
git add README.md
git commit -m "バグ修正の作業を想定したコミット"
1つ目のコマンドは、ブランチの切り替えを行う「switch」を使っていて、なおかつ「-c」のオプションを使って「ブランチの作成 + 切り替え」を 1つのコマンドで行っています。
2つ目のコマンドで、1つ目のコマンド実行後の状態を確認しています。
実行後の画面は以下のとおりで、bugfixブランチが作成されていることと、bugfixブランチに切り替えが行われていることが分かります。
その後にエディタ上で、適当に「README.md」を編集してファイルの変更が発生するようにしました。
その後、その変更をコミットする流れとなっています。
main のほうでの変更と別ブランチからのマージ
あとは、main のほうでの変更を加えてみるのと、別ブランチからのマージを試します。
以下は、main のほうでの変更を加えてみる一連の流れです。
git switch main
git branch
【※ この部分でエディタで「README.md」を編集】
git add README.md
git commit -m "mainで修正を加えてみる"
1つ目は「switch」を使ったブランチの切り替えです。
2つ目のコマンドで、今回も 1つ目のコマンド実行後の状態を確認しています(今回の場合は、以下のように main に切り替わっていることを確認)。
その後、以下を実行して bugfixブランチで行った作業を main のほうに反映させます。
git merge bugfix
今回、自分が進めた手順では同じファイルの競合する箇所を編集していたので、以下のとおり自動でのマージは失敗しました。もし競合しない状態であれば、この時点で自動的なマージが完了して、bugfixブランチでの作業内容が main のほうに反映された状態になります。
競合の解決
それでは、競合を解決していきます。
以下は、「README.md」をエディタで開いた時の状態です。
ちなみにマージ前の状態は、それぞれ以下となります。
"# ブランチのテスト用のリポジトリ > mainの側で変更を加える"
"# ブランチのテスト用のリポジトリ"
X:バグ修正作業を想定した編集
上記の競合が起こった状態のものをテキストで書きだすと、以下となります。
<<<<<<< HEAD
"# ブランチのテスト用のリポジトリ > mainの側で変更を加える"
=======
"# ブランチのテスト用のリポジトリ"
X:バグ修正作業を想定した編集
>>>>>>> bugfix
これに関して、エディタ「<<<<<<< HEAD」「=======」などのマーカーを削除したり、競合した部分を意図した内容に集約したりして、以下としました。
"# ブランチのテスト用のリポジトリ > mainの側で変更を加える"
X:バグ修正作業を想定した編集
競合が発生してその解決のための対応を行った場合、マージが自動で行われない状態となっているため、さらにコミットなどの作業が必要です。
今回の場合、エディタで競合を解消した後に以下のコマンドを実行し、競合解決後の内容反映作業を完了させました。
git add README.md
git commit -m "'bugfix'ブランチをマージ"
ログの確認とブランチの削除
念のため、ログを「--graph」をつかえたコマンドで確認してみます。
git log --graph
その結果、意図したとおりの流れになっていることが確認できました。
※ 以下が、上でも掲載していた 1つ目のお試しの流れです
あと、bugfixブランチの削除も試します。
以下は、状態の確認をまじえたブランチの削除の流れのコマンドと、その実行結果です。
git branch
git branch -d bugfix
git branch
git branch -d bugfix
を実行した前後の出力結果を見ると、bugfixブランチが削除できていることが分かります。
2つ目の内容を試す
次は 2つ目の内容を試してみます。
試す流れ
先ほどは main と bugfix で変更を加える流れにしていましたが、2つ目のお試しでは作業 2つを main 以外で行うことにします。
具体的には、以下のとおりです。
実際の内容
それでは、実際に試していきます。
まずはベースとなるテスト用のリポジトリを作成し、そこで以下の状態を作っていきます。
ベースを準備する
まずは以下のコマンドで、ベースとなる内容を準備します。
git init
echo "# ブランチのテスト2" > test2.md
echo "2つ目のファイルを作成" > sample.txt
git status
git add *
git commit -m "A:最初の状態"
git log --oneline
でログを確認すると、以下の状態になっています。
ブランチの作成と作業
先ほどと同じように、ブランチでの作業を行います。
以下は、2つのブランチでの作業の手順です。
git switch -c bugfix
【※ この部分でエディタで「test2.md」を編集】
git add test2.md
git commit -m "X:バグ修正の作業を想定したコミット"
さらに続きを進めます(※ 以下、途中の状態を確認するコマンドもまぜています)。
git branch
【※ この部分でエディタで「sample.txt」を編集】
git add sample.txt
git commit -m "O1:機能追加作業を想定したコミット"
【※ この部分でエディタで「sample.txt」をさらに編集】
git add sample.txt
git commit -m "O2:さらなる機能追加作業を想定したコミット"
git log --oneline
以下は、最後の行のログ確認用コマンドを実行した時の出力です。
作業した内容は、意図通りに反映されていそうです。
マージを行う
最後に main へのマージです。
以下の図の「C」「D」にあたる部分です。
ここまでの状態だと featureブランチ上で作業をしている状態なので、以下を実行して main に切り替えてから他 2つのブランチで行った作業を main へと反映させます(※ 以下はブランチの削除と、途中の状態を確認するコマンドをまじえたものになっています)。
git switch main
git merge bugfix
git merge feature
git branch
git branch -d bugfix
git branch -d feature
git branch
git log --graph
上記の最終行の実行結果を以下に掲載します。
無事、2つのブランチで行った作業が取り込まれており、想定通りの状態になっていそうです。
その他
switchコマンド と checkoutコマンド
ブランチの利用に関する記事を見ていると、「switch」ではなく「checkout」を使った例を見かけることがあるかもしれません。
それについて少し触れておきます。
checkoutこまdの について
checkoutコマンドは、ブランチの切り替えもに利用できるコマンドでありつつ、それ以外にもファイルの復元・特定のコミットのチェックアウトなど、複数の機能を持ったコマンドです。
例えば checkoutコマンドの例を書くと、今回の記事で使った git switch -c bugfix
というコマンドは、checkoutコマンドでは git checkout -b bugfix
というコマンドになります。
今回使った switchコマンドは、Git 2.23 で導入された新しいコマンドで、それ以前は checkoutコマンドのみが使える状態でした。そのため過去の記事などを検索すると checkoutコマンドを使った例と switchコマンドが混在した結果が出てくることもあるかと思います。
今回のブランチの操作を行うには、switchコマンドを使うほうが分かりやすい操作になるかと思います。