mike-neckのブログ

Java or Groovy or Swift or Golang

今更だけどgit rebaseとか復習する

ほとんどのエンジニアには必要のない記事。サルでも分かるGit入門のほうが丁寧だし、誰にでもわかるように書かれているので、そっちを見たほうがよい。アリスが好きなら、そっちで解説を読んだ方がよい。なお、練習用にgistを使った。

目的

git rebaseをこわがらずに実行できるようにするための練習

なんか、一人でやる場合がほとんどで、かつmasterで作業しているという訓練されていなさを発揮しているので…(´・ω・`)

git merge

git mergeをすると、いつもビビってしまうので、まずこれから。

やったのは次のとおり

  1. 最初のコミットからtopicブランチを作る
  2. topicブランチでファイルを編集
  3. masterに戻ってファイルを編集
  4. masterブランチでtopicブランチをマージ
topicブランチでファイルを編集

topicブランチでの編集後の状態

$ git log --oneline -5
bb7a41f mergeをやりたいことに追加
bf8af35 

topicでの変更は次のとおり

$ git diff bf8a bb7a
diff --git "a/git-rebase\343\201\256\345\213\211\345\274\267.txt" "b/git-rebase\343\201\256\345\213\211\345\274\267.txt"
index c955626..96b5917 100644
--- "a/git-rebase\343\201\256\345\213\211\345\274\267.txt"
+++ "b/git-rebase\343\201\256\345\213\211\345\274\267.txt"
@@ -4,3 +4,5 @@ git rebaseの勉強
 #### やること
 
 1. やることを埋める
+1. mergeしてみよう
+
masterに戻ってファイルを編集

topicでの変更はうっちゃっておいて、masterで編集する。

$ git log --oneline -5
a872900 目標を追加した
bf8af35 

masterでの編集は次のとおり。

$ git diff a872 bf8a
diff --git "a/git-rebase\343\201\256\345\213\211\345\274\267.txt" "b/git-rebase\343\201\256\345\213\211\345\274\267.txt"
index 0417a5d..c955626 100644
--- "a/git-rebase\343\201\256\345\213\211\345\274\267.txt"
+++ "b/git-rebase\343\201\256\345\213\211\345\274\267.txt"
@@ -1,10 +1,6 @@
 git rebaseの勉強
 ===
 
-#### 目標
-
-git rebaseをググラなくてもよい程度には勉強する
-
 #### やること
 
 1. やることを埋める
masterブランチでtopicブランチをマージ

$ git merge topicを実行すると、次のようにコミットメッセージを編集する状態になる

Merge branch 'topic'

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

コミットメッセージを編集すると次のように表示される

$ git merge topic
Auto-merging git-rebaseの勉強.txt
Merge made by the 'recursive' strategy.
 "git-rebase\343\201\256\345\213\211\345\274\267.txt" | 2 ++
 1 file changed, 2 insertions(+)

ログは次のとおり

$ git log --oneline -5
37dfecf topic ブランチをマージした
a872900 目標を追加した
bb7a41f mergeをやりたいことに追加
bf8af35 

git pull

とりあえず、gistで編集してから、git pullしてみる

$ git pull
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From gist.github.com:/ecd15bca9c33098a526e
   37dfecf..76c7af5  master     -> origin/master
Updating 37dfecf..76c7af5
Fast-forward
 ...-rebase\343\201\256\345\213\211\345\274\267.txt" => "git-rebase\343\201\256\345\213\211\345\274\267.md" | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename "git-rebase\343\201\256\345\213\211\345\274\267.txt" => "git-rebase\343\201\256\345\213\211\345\274\267.md" (87%)

変更のログは次のとおり

$ git log --oneline -10
76c7af5 
ce9bbf4 
37dfecf topic ブランチをマージした
a872900 目標を追加した
bb7a41f mergeをやりたいことに追加
bf8af35 

ちなみに

  • ce9bbf4 はファイル名を変更(拡張子.txtだったのを.mdに変更)
  • 76c7af5 は「git pullしてみる」をやることリストに追加

やっとgit rebase

  1. topicブランチ上でgit rebase masterをする
  2. masterブランチ上でgit rebase topicをする
1.のための準備

最初のマージの時と同様に、mastertopicで異なる箇所を修正しておく

masterの変更の状態

$ git branch
* master
  topic
$ git log --oneline -10
6b45fb9 
76c7af5 
ce9bbf4 
37dfecf topic ブランチをマージした
a872900 目標を追加した
bb7a41f mergeをやりたいことに追加
bf8af35 

topicの変更の状態

$ git checkout topic
Switched to branch 'topic'
$ git log --oneline -10
7f37f40 rebase をやりたいことに追加
76c7af5 
ce9bbf4 
37dfecf topic ブランチをマージした
a872900 目標を追加した
bb7a41f mergeをやりたいことに追加
bf8af35 
1. git rebase masterの実行
$ git branch
  master
* topic
mike-no-MacBook-Air:ecd15bca9c33098a526e mike$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: rebase をやりたいことに追加
Using index info to reconstruct a base tree...
M   "git-rebase\343\201\256\345\213\211\345\274\267.md"
<stdin>:11: new blank line at EOF.
+
warning: 1 line adds whitespace errors.
Falling back to patching base and 3-way merge...
Auto-merging git-rebaseの勉強.md

この時のログは次のとおり

$ git log --oneline -10
aa75dfb rebase をやりたいことに追加
6b45fb9 
76c7af5 
ce9bbf4 
37dfecf topic ブランチをマージした
a872900 目標を追加した
bb7a41f mergeをやりたいことに追加
bf8af35 
2.のための準備
  • 一度topicmasterにマージしておく
  • topicブランチを一度削除した後、再度topicブランチを作る
  • masterで変更する
  • topicで変更する

masterでの変更は次のとおり

$ git branch
* master
  topic
$ git log --oneline -10
392ba3c 
fa4a0c7 topicのmasterへのマージを追加
aa75dfb rebase をやりたいことに追加
6b45fb9 
76c7af5 
ce9bbf4 
37dfecf topic ブランチをマージした
a872900 目標を追加した
bb7a41f mergeをやりたいことに追加
bf8af35 

更新内容は次のとおり

$ git diff fa4a 392b
diff --git "a/git-rebase\343\201\256\345\213\211\345\274\267.md" "b/git-rebase\343\201\256\345\213\211\345\274\267.md"
index b38bbf5..96ad453 100644
--- "a/git-rebase\343\201\256\345\213\211\345\274\267.md"
+++ "b/git-rebase\343\201\256\345\213\211\345\274\267.md"
@@ -9,7 +9,7 @@ git rebaseをググラなくてもよい程度には勉強する
 
 1. やることを埋める
 1. ~~mergeしてみよう~~
-1. git pullしてみる
-1. topicブランチで`git rebase master topic`をしてみる
+1. ~~git pullしてみる~~
+1. ~~topicブランチで`git rebase master topic`をしてみる~~
 1. 一度topicブランチをmasterにマージする

topicでの変更は次のとおり

$ git checkout topic
Switched to branch 'topic'
$ git log --oneline -10
18e37c7 git rebase topicを追加
fa4a0c7 topicのmasterへのマージを追加
aa75dfb rebase をやりたいことに追加
6b45fb9 
76c7af5 
ce9bbf4 
37dfecf topic ブランチをマージした
a872900 目標を追加した
bb7a41f mergeをやりたいことに追加
bf8af35 

topicでの更新内容

$ git diff fa4a 18e3
diff --git "a/git-rebase\343\201\256\345\213\211\345\274\267.md" "b/git-rebase\343\201\256\345\213\211\345\274\267.md"
index b38bbf5..9d686b9 100644
--- "a/git-rebase\343\201\256\345\213\211\345\274\267.md"
+++ "b/git-rebase\343\201\256\345\213\211\345\274\267.md"
@@ -12,4 +12,5 @@ git rebaseをググラなくてもよい程度には勉強する
 1. git pullしてみる
 1. topicブランチで`git rebase master topic`をしてみる
 1. 一度topicブランチをmasterにマージする
+1. masterブランチで`git rebase topic`をしてみる
2. master上でgit rebase topicを実行
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git rebase topic
First, rewinding head to replay your work on top of it...
Applying: 
Using index info to reconstruct a base tree...
M   "git-rebase\343\201\256\345\213\211\345\274\267.md"
Falling back to patching base and 3-way merge...
Auto-merging git-rebaseの勉強.md

ログを見ると次のようになっている

  • mastertopicでのコミット18e37c7が挿入される
  • masterでのコミットが392ba3c153638fに変更される
$ git log --oneline -10
153638f 
18e37c7 git rebase topicを追加
fa4a0c7 topicのmasterへのマージを追加
aa75dfb rebase をやりたいことに追加
6b45fb9 
76c7af5 
ce9bbf4 
37dfecf topic ブランチをマージした
a872900 目標を追加した
bb7a41f mergeをやりたいことに追加

なお、コミット392ba3cはgist上で行ったので、歴史が変わってしまっている。したがって、この状態からgit pushしようとすると、当然エラーになる

$ git push origin master
To git@gist.github.com:/ecd15bca9c33098a526e.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@gist.github.com:/ecd15bca9c33098a526e.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

git reset

上記の状態だとpushできないので、git reset --hardmasterに取り込んだtopicのコミット18e3715363をなかったことにする

$ git reset --hard 392ba
HEAD is now at 392ba3c 

この状態のログは次のようになる

$ git log --graph --all --oneline --decorate -5
* 18e37c7 (topic) git rebase topicを追加
| * 392ba3c (HEAD, origin/master, origin/HEAD, master) 
|/  
* fa4a0c7 topicのmasterへのマージを追加
* aa75dfb rebase をやりたいことに追加
* 6b45fb9 

pushするために、後はtopic上でgit rebase masterをするか、git rebase master topicをする

今回はやってなかったgit rebase master topicの方をする

$ git rebase master topic
First, rewinding head to replay your work on top of it...
Applying: git rebase topicを追加
Using index info to reconstruct a base tree...
M   "git-rebase\343\201\256\345\213\211\345\274\267.md"
Falling back to patching base and 3-way merge...
Auto-merging git-rebaseの勉強.md

この状態でのログは次のようになる

$ git log --graph --all --oneline --decorate -5
* 96aa7f5 (HEAD, topic) git rebase topicを追加
* 392ba3c (origin/master, origin/HEAD, master) 
* fa4a0c7 topicのmasterへのマージを追加
* aa75dfb rebase をやりたいことに追加
* 6b45fb9 

pushまでは次のとおり

$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git merge topic
Updating 392ba3c..96aa7f5
Fast-forward
 "git-rebase\343\201\256\345\213\211\345\274\267.md" | 1 +
 1 file changed, 1 insertion(+)
$ git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 351 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To git@gist.github.com:/ecd15bca9c33098a526e.git
   392ba3c..96aa7f5  master -> master

まとめ

僕が普段やる程度の内容だと次に注意していればよいかな…

  • git rebase master topicgit checkout mastergit merge topicgit push
  • git rebase topic masterは茨の道というか無意味なのでやらない

以上、メモというか走り書きというか、あまりまとまってはいない