matobaの備忘録

育児しながら働くあるエンジニアの記録

gitのrebaseを簡単に試して見た。

gitのrebaseがよくわかっていない部分があるので、勉強したいと思う。

このあたりを読んでも文章が長くていまいちしっくりこない。というか矢印の向きとか図形の定義がよくわからなかったり、何を見たらいいのかわからなくて戸惑う。

Git - リベース

最近、何となく進んできた理解では、rebaseは、「今使っているブランチを派生させる場所を変更するコマンド」というイメージになっている。

その理解が正しいのかを確かめたい。

まずは、ローカルに動作確認用のリポジトリを作る。

$ cd git-rebase-test/
$ git init
Initialized empty Git repository in /Users/mtb/work/git-rebase-test/.git/
$ ll
.    ..   .git

とりあえず、masterブランチに、ファイルを一つ作る。

$ echo test1 >> ChangeLog.txt
$ cat ChangeLog.txt
test1
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    ChangeLog.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add ChangeLog.txt
$ git commit -m "test1 commit"
[master (root-commit) 8296084] test1 commit
 1 file changed, 1 insertion(+)
 create mode 100644 ChangeLog.txt
$ git log
commit 82960845db034126e9ff913e7ed3bc30c2034165 (HEAD -> master)
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:32:55 2017 +0900

    test1 commit
$ git branch -a
* master

ここから、ブランチを作ってチェックアウトする。ブランチ名は、 branch1 にしよう。

$ git branch branch1
$ git checkout branch1
Switched to branch 'branch1'
$ git branch
* branch1
  master

追記してコミットする。3回やろう。

$ echo branch1-1 >> ChangeLog.txt
$ cat ChangeLog.txt
test1
branch1-1
$ git add ChangeLog.txt
$ git commit -m "branch1-1 commit"
[branch1 000ab89] branch1-1 commit
 1 file changed, 1 insertion(+)
$ echo branch1-2 >> ChangeLog.txt
$ git add ChangeLog.txt
$ git commit -m "branch1-2 commit"
[branch1 42ea439] branch1-2 commit
 1 file changed, 1 insertion(+)
$ echo branch1-3 >> ChangeLog.txt
$ git add ChangeLog.txt
$ git commit -m "branch1-3 commit"
[branch1 ca1720e] branch1-3 commit
 1 file changed, 1 insertion(+)

ファイルの中身とgitのログを見る。ChangeLog.txtに3回のコミットが追加されている。

$ cat ChangeLog.txt
test1
branch1-1
branch1-2
branch1-3
$ git log
commit ca1720e8913b2e0a8ec7b8767eac9a8c326464fb (HEAD -> branch1)
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:41:05 2017 +0900

    branch1-3 commit

commit 42ea439a6ba204468c0e037b640b36f08d5dbe0e
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:40:52 2017 +0900

    branch1-2 commit

commit 000ab898c73855aa0265025bd805ae052d38386a
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:39:57 2017 +0900

    branch1-1 commit

commit 82960845db034126e9ff913e7ed3bc30c2034165 (master)
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:32:55 2017 +0900

    test1 commit

次は、masterブランチのChangeLog.txtに修正を加えよう。それぞれは、別のコミットにする。

  • ChangeLog.txt の先頭行に「ChangeLogs」を追加
  • ChangeLog2.txt に 「test2」
$ git checkout master
Switched to branch 'master'
$ vim ChangeLog.txt
$ cat ChangeLog.txt
ChangeLogs
test1
$ git add ChangeLog.txt
$ git commit -m "change logs commit"
[master 5f50b58] change logs commit
 1 file changed, 1 insertion(+)
$ echo test2 >> ChangeLog2.txt
$ cat ChangeLog2.txt
test2
$ git add ChangeLog2.txt
$ git commit -m "change log2 add"
[master f76437a] change log2 add
 1 file changed, 1 insertion(+)
 create mode 100644 ChangeLog2.txt

git logを見て見る。masterブランチに二つのコミットがついた状態になっている。

$ git log
commit f76437af8af7fd44e09170968aeb45f1771674b1 (HEAD -> master)
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:47:51 2017 +0900

    change log2 add

commit 5f50b58689b86514224c4b2b59caa1a809954ea8
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:47:00 2017 +0900

    change logs commit

commit 82960845db034126e9ff913e7ed3bc30c2034165
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:32:55 2017 +0900

    test1 commit

banch1 は、commit 82960845db034126e9ff913e7ed3bc30c2034165 から派生したブランチだけど、新しく含まれている2つのブランチも取り込みたい。

こういう時にrebaseを使う。(多分。) 使って見る。

まずは、取り込みたいブランチにcheckoutする。そして、masterにrebaseする。 じゃあ色々ログが流れる。 ログを読むとわかるけど、masterのheadに戻って、そこから新しいコミットを適応していく。

$ git checkout branch1
Switched to branch 'branch1'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: branch1-1 commit
Using index info to reconstruct a base tree...
M   ChangeLog.txt
Falling back to patching base and 3-way merge...
Auto-merging ChangeLog.txt
Applying: branch1-2 commit
Using index info to reconstruct a base tree...
M   ChangeLog.txt
Falling back to patching base and 3-way merge...
Auto-merging ChangeLog.txt
Applying: branch1-3 commit
Using index info to reconstruct a base tree...
M   ChangeLog.txt
Falling back to patching base and 3-way merge...
Auto-merging ChangeLog.txt

修正後のファイルを見て見ると、無事にマージされている様子。

$ ll
.              ..             .git           ChangeLog.txt  ChangeLog2.txt
$ cat ChangeLog.txt
ChangeLogs
test1
branch1-1
branch1-2
branch1-3
$ cat ChangeLog2.txt
test2

ログを見てもそうなっている。

$ git log
commit 0e639b0330dfebc47e503f7eb6e95091169c2765 (HEAD -> branch1)
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:41:05 2017 +0900

    branch1-3 commit

commit 3c301cf904baa9e61202c401b51270eb43668a60
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:40:52 2017 +0900

    branch1-2 commit

commit 02ebe3df591fefbab1d2d7d438aa40becef5526b
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:39:57 2017 +0900

    branch1-1 commit

commit f76437af8af7fd44e09170968aeb45f1771674b1 (master)
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:47:51 2017 +0900

    change log2 add

commit 5f50b58689b86514224c4b2b59caa1a809954ea8
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:47:00 2017 +0900

    change logs commit

commit 82960845db034126e9ff913e7ed3bc30c2034165
Author: mtb_beta <example@example.com>
Date:   Thu Nov 30 07:32:55 2017 +0900

    test1 commit

終わり

  • gitのrebaseを簡単に試して見た。
  • 当初抱いていた「今使っているブランチを派生させる場所を変更するコマンド」というイメージは、ある意味では間違ってないけど、厳密にいうと違う。
  • (多分、)指定したブランチのHEADから、現在のブランチに加えられたコミットを再適用するのがrebase。(ややこしい)
  • とはいえ、git reset ってなんだろう。とか HEAD って僕の理解で合ってるのかな。とか疑問はまだあるので、これもそのうち確かめたい。