Gitの学び始めは毎日触ることが重要である。今回はそんなときにピッタリのお題だ。
この記事の対象者
Gitとを学び始めて使えるようになりたいと思っている人。GitHubとの連携ができるようになりたい人。なお、gitに比較的新しく加わった変更はここでは使用しない。switchコマンドは使わず、メインとなるブランチもmainではなくmasterで行う。
git_basicフォルダの作成
デスクトップにgit_basicフォルダを作成し、移動する
$ cd ~/desktop
$ mkdir git_basic
$ cd git_basic
git init
作成したgit_basicフォルダの歴史を管理していきたい。そういったときにはその管理したいフォルダでgit initを行う。Gitはフォルダごとに歴史を管理していく。
$ git init
ファイルを作成していこう。以下のようなMonth.txtを作成する
January
February
March
April
May
June
July
August
September
October
November
December
ファイルの保存をしたら以下のコマンドを打つ
$ git status
このコマンドは現在のGit管理の状態を教えてくれる極めて重要なコマンドだ。
休憩の後など、作業の節目にはとりあえずgit statusして現在の状況を確認する感じだ。

赤文字で新しいファイルが作成されたことを教えてくれている
git add
それではこの変更で歴史を作っていこう。Gitでは歴史を作るためにステージングエリアにファイルを上げる必要がある。以下のコマンドを打つ
$ git add Month.txt
こうすることによってMonth.txtをステージングエリアに置くことができる
git commit
そして、実際に歴史を作るコマンドがcommitだ。以下のコマンドを打つ
$ git commit -m"Month.txt作成"
-mはメッセージオプションでこうすることでコミットメッセージを設定できる。
git graph
commitを行ったらgraphで確認する。このgit graphというのは正式なコマンドではないが、非常に便利なので未設定の人は以下のコマンドを打って使えるようにしておく
$ git config --global alias.graph "log --graph --date-order --all --pretty=format:'%h %Cred%d %Cgreen%ad %Cblue%cn %Creset%s' --date=short"
設定が終わったら以下のようにgit graphで確認
$ git graph

コミットオブジェクトが作成された。これでこのフォルダの歴史が一つ出来上がったことになる。このフォルダの状態にはいつでも戻ってくることができる。いわば、ゲームのセーブポイントのようなものだ。
branch
今はmasterブランチしかないが、実際の開発では、開発ブランチを作成してそこで作業を進めていくことになる。実際にやってみよう。以下のコマンドを実行
$ git checkout -b dev
これで、新しくdevブランチが作成され、そこにcheckoutすることができる。
git graphしてみよう。
$ git graph

このコミットオブジェクト(セーブポイント)をmasterブランチとdevブランチが指すようになった。HEAD->devというのは、現在devブランチ上にいるという意味だ。
devブランチで開発
ではdevブランチにいる状態で、以下のように新規にSeason.txtを作成しよう。
Spring
Summer
Autumn
Winter
作成が終了したら、コミットオブジェクトを以下のように作成する。
$ git add .
$ git commit -m"Season.txt作成"
commitをしたらあとは常にgit graphする癖をつけておくと良い。以下のように実行
$ git graph

一つ新しいコミットオブジェクト(セーブポイント)が作成され、そこをdevブランチが指している。
merge
devブランチで行った開発をmasterブランチに反映させたい。その場合はまず、masterブランチに移動し、mergeを行う。以下のように実行
$ git checkout master
$ git merge dev
これでdevで行われた作業をmasterブランチにも反映させることができた。
mergeの後もgit graphをする癖をつけておくと良い。以下のようにコマンド
$ git graph

masterブランチが追いついたことがわかる。
どんどんコミット
では引き続き開発を続けよう、まずはdevブランチに移動する
$ git checkout dev
Color.txtを以下のように作成する。
white
black
red
blue
yellow
作成したら。以下のようにadd & commit
$ git add .
$ git commit -m"Color.txt作成"
お題
ここで、さきほどやったようにmasterブランチにdevで行われた変更を反映させてみよう。
解
$ git checkout master
$ git merge dev
できたであろうか?Gitはとにかく繰り返し行って覚えていくしかない。
git graphしてみよう。
$ git graph

これで3つのコミットオブジェクト(セーブポイント)が作成された。
不要になったブランチの削除
不要になったdevブランチを削除しよう。以下のようにコマンド
$ git branch -d dev
これで不要になったブランチを削除することができた。Gitにおいてブランチはコミットオブジェクトを指すポインタに過ぎないので、気軽にブランチを作成&削除してしまってOKだ。git graphで現状を確認しよう
$ git graph

conflict
masterブランチが指すコミットオブジェクト(上写真だとe9ff7a5)から2つの作業を並行して行いたいので2つのブランチを作成する。以下のようにコマンド
$ git branch featA
$ git branch featB
git graphで確認しよう。

まずはfeatAをcheckoutとする
$ git checkout featA
Color.txtを開き末尾にgoldを追加し、保存する。
white
black
red
blue
yellow
gold
add & commit する。ファイルの変更のみの場合は以下のコマンドを使うと1行でコミットオブジェクトを作成できる。(新規作成ファイルがある場合、この方法は不可)
$ git commit -am"末尾にgold追加"
今度はfeatBにチェックアウトして末尾にsliverを加え保存する。
$ git checkout featB
white
black
red
blue
yellow
silver
ファイルを保存して、commitオブジェクトを作成する。コマンドは以下
$ git commit -am"末尾にsliver追加"
git graphをしてみよう。

masterブランチから2つのブランチが分岐して作業をしていることがわかる。
masterブランチにこの2つのブランチで行った変更をmergeしてみよう。
masterブランチに移動して、featAを以下のようにmergeする。
$ git checkout master
$ git merge featA
このmergeは問題なく行える。次にmasterにfeatBもmergeしてみよう。以下のようにコマンド
$ git merge featB
すると以下のようにconflict(衝突)が発生する。

featAブランチでは末尾にgoldをfeatBブランチでは末尾にsilverを追加したため、Gitは末尾をどうしたらいいのかがわからなくなっている。こういったときにGitはCONFLICTという状態を発生させてmergeを中断する。
conflictが発生しているColor.txtをエディタで開いてみよう。

特殊なマーカーが自動的に挿入されていて、どの部分がコンフリクトしているのかを教えてくれている。では編集してをして求める状態にしていこう。今回は両方を採用することにする。以下のようにマーカーを削除してファイルを保存しよう。
white
black
red
blue
yellow
gold
silver
ファイルを編集しただけでは,mergeは完了しない。以下のようにadd & commitすることでmergeが完了する。
$ git add .
$ git commit -m"コンフリクトが発生したが両方採用"
無事にmergeできたので、git graphしよう。
$ git graph

2つの変更を取り込んだコミットオブジェクトが作成された!
不要になったfeatA,featBブランチを削除しよう。コマンドは以下
$ git branch -d featA featB
なにか作業したらgit graph。
$ git graph

rebaseを用いる
先ほど、mergeを用いて2つのコミット内容を統合する処理を行ったが、rebaseを用いてまとめることもできる。やってみよう。
まずは、以下のようにreflogをして過去の履歴を見てみよう。
$ git reflog
Color.txtを作成した直後のハッシュを確認する。

reset –hard を使ってそのときの状態に戻る
$ git reset --hard 0e87cfb
現状確認のgit graph

ここから先ほどと同じようにfeatA,featBを作成する。
$ git branch featA
$ git branch featB
featAにチェックアウトし、goldを末尾に追加した後に
featBにチェックアウトしてsilverを末尾に追加してcommit する
(先ほどと同じ状況)

masterに移動して、featAブランチをマージする(ここまではさきほどと同様)

ここで、featBにチェックアウトする
$ git checkout featB
ここで以下のようにrebaseのコマンドを打つ
$ git rebase master
これは、このブランチが現在のmasterから始まったと仮定して処理の統合を図るものだ。

最後の行に関して矛盾が発生しているのでここでもコンフリクトが発生する。
先ほどと同様にコンフリクトが発生しているColor.txtを編集し保存する(両方採用する)
$ git add .
$ git rebase --continue

コミットメッセージの編集画面が開くので、変更があればここで編集する。今回はそのまま保存して閉じる。
これでリベース完了だ。git graphしてみてみよう。

マージしたときとは違い分岐が発生していない。masterもマージしよう。
$ git checkout master
$ git merge featB
このようにリベースを用いるとコミットログがきれいになるという特徴がある。
このように異なるブランチ間で行われた作業をまとめるにはmergeとrebaseがある。状況に応じて使い分けていくとよいだろう。
コメント