Gitコマンド入門::Gitブランチ機能(rebase,merge)第六十二回

5 min read読了の目安(約4800字

みなさんこんにちは! 今回からは、rebase,mergeの学習を進めて行きますね。fast-forward は、コマンドを実行した結果としても、よく表示されるワードですけど、なんとなく分かるようでわかりずらいです。まあ~、Googleで翻訳すると、早送りしてブランチを合体させる! っていうことなので、データーを上下に重ねるというよりも、データーを前後につなげるってことかな~ぐらいのイメージですけどね。(^▽^;)

前回、第六十一回の記事はこちらから!

https://zenn.dev/shiozumi/articles/9c47ca39a03731

git本家本元の情報はこちらから!

https://git-scm.com/book/ja/v2

今回からの課題は、ここを参考にしています!

https://git-scm.com/book/ja/v2/Git-のブランチ機能-リベース

3.6 Git のブランチ機能 - リベース

merge のイメージ図


ローカルmainブランチ、ローカルsubブランチともに変更して、2つのコミットをマージ処理

rebase のイメージ図


ローカルmainブランチ、ローカルsubブランチともに変更するけども、ローカルsubブランチの変更を、ローカルmainブランチの変更として、取り込んでしまう。

この解釈で正解なのかは、分かりませんけど~(^▽^;)

いままでの私の経験上に基づいての解釈です。悪しからず!

まずは、merge を行ってみます!

$ mkdir func0062_merge && cd $_

// いつもの git init
$ git init

// README.md を作成!
$ echo "func0062" > README.md

// add,commit
$ git add README.md
$ git commit -m "1st" // <!-- コメントは、1st

// master ブランチから、subブランチ作成
$ git checkout -b sub
Switched to a new branch 'sub'

// sub.txt を作成!
$ echo "3rd sub" > sub.txt

// add,commit
$ git add sub.txt
$ git commit -m "3rd sub"  // <!-- コメントは、3rd sub

$ git switch master
Switched to branch 'master'

// ブランチ名を、master から、main に変更!
$ git branch -M main

// main.txt を作成!
$ echo "2nd main" > main.txt

// add,commit
$ git add main.txt
$ git commit -m "2nd main" // <!-- コメントは、2nd main

// では、マージ処理を実行!
$ git merge sub

Merge made by the 'recursive' strategy.
 sub.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 sub.txt
 
// log で履歴を確認!
$ git log main --graph --oneline
*   99654de (HEAD -> main) Merge branch 'sub' into main
|\
| * e7ebd3a (sub) 3rd sub
* | 9dcfcac 2nd main
|/
* f0bee8c 1st

$ git cat-file -p main
tree 5d42770fb70f03ad74185447928e5255fdbd161d
parent 9dcfcacf666ba69cf1b6607e94eadabf5e258e7d
parent e7ebd3ad13a9c1ced17f78d072d94d166b0b859a
// 中略~
//  マージ処理なので、マージ元の親となるハッシュ値が、
//  2つありますね。9dcfcac~ e7ebd3a~

rebase も前半は、merge と全く同じです。

// フォルダーを新規に作成します!
$ mkdir func0062_rebase && cd $_

// いつもの git init
$ git init

// README.md を作成!
$ echo "func0062" > README.md

// add,commit
$ git add README.md
$ git commit -m "1st" // <!-- コメントは、1st

// master ブランチから、subブランチ作成
$ git checkout -b sub
Switched to a new branch 'sub'

// sub.txt を作成!
$ echo "3rd sub" > sub.txt

// add,commit
$ git add sub.txt
$ git commit -m "3rd sub"  // <!-- コメントは、3rd sub

$ git switch master
Switched to branch 'master'

// ブランチ名を、master から、main に変更!
$ git branch -M main

// main.txt を作成!
$ echo "2nd main" > main.txt

// add,commit
$ git add main.txt
$ git commit -m "2nd main" // <!-- コメントは、2nd main

// ここまでは、merge と全く同です!

では、rebase を行ってみます!

// まずは、subブランチに移動してからの~
$ git checkout sub
Already on 'sub'

// main に対してリベースします!
$ git rebase main
First, rewinding head to replay your work on top of it...
Applying: 3rd sub

// そして、再び、main に戻って
$ git checkout main
Switched to branch 'main'

// そして、merge 処理!
$ git merge sub
Updating 28ab67c..a7f41c4
Fast-forward
 sub.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 sub.txt
 
// log で履歴を確認!
$ git log --graph --oneline
* a7f41c4 (HEAD -> main, sub) 3rd sub
* 28ab67c 2nd main
* 6937be6 1st
// rebase 処理を行った場合は、subブランチの、3rd sub コミットが、
// mainブランチの処理として、2nd main の後に繋がっていますね。

$ git cat-file -p main
tree 5d42770fb70f03ad74185447928e5255fdbd161d
parent 28ab67c7f694be86260dcb58ccb080f638624083
// 中略~
//  こちらは、マージ処理とは異なって、親のハッシュ値が、ひとつです。

merge と rebase のコマンド操作手順の違い。

rebase の方が、merge よりも、ひと手間多くなっていますね。merge する場合は、mainブランチに移動して、git merge で完了ですが、rebase する場合は、マージする前に一度、subブランチに移動して、rebase main を実行した後で、マージする必要があります。

  1. merger は、merge のみでOK!
  2. rebase は、rebase してから、merger で完了!

では、subブランチの状態を確認しましょう!

// func0062_merge フォルダーに移動してから。

[func0062_merge]$ git log sub --oneline --graph
* e7ebd3a (sub) 3rd sub
* f0bee8c 1st
// merge した場合の、subブランチは、3rd sub のままです。

// func0062_rebase フォルダーに移動してから。
[func0062_rebase]$ git log sub --oneline --graph
* a7f41c4 (HEAD -> main, sub) 3rd sub
* 28ab67c 2nd main
* 6937be6 1st

// mainブランチの履歴も、subと全く同じですね。
[func0062_rebase]$ git log main --oneline --graph
* a7f41c4 (HEAD -> main, sub) 3rd sub
* 28ab67c 2nd main
* 6937be6 1st

// rebase したほうは、mainブランチと、subブランチの内容が、
// 全く同一になっているんですよね~

rebase 処理後は、main,sub両方の履歴が全く同じ!

git rebase main を実行した時点で、おそらく、28ab67c 2nd main のコミットを、取り込んで、その後ろに、a7f41c4 3rd sub コミットを繋げたのでしょう。なので、mainブランチに戻って、git meger sub を実行したときは、すでに完了していて、subブランチのポインターをそのまま、mainブランチにコピーしただけだと思います。

それでは、今回はここまで、お疲れ様でした!

https://zenn.dev/shiozumi/articles/3ceb2ce5bab157
https://twitter.com/esmile2013