なんなのかと
rebase
品質を落とす、品のない振る舞いをする
git rebase
つかいみち : ブランチにmasterの変更を取り込む
例えば、こんな感じに、 master
と、branch_b
がある場合...
* ac7957d Add 'd' in a.txt | * 9aa15f9 (refs/heads/branch_b) Add 'c' in b.txt | * b129f6c Add b.txt |/ * 3d940b6 Add 'b' in a.txt * 26ba7e0 Add a.txt
git checkout branch_b git rebase master
git rebase master
を実行すると、master
の HEAD
の上に、 branch_b
が乗っかる感じになる
- ブランチ分岐後に追加された変更
ac7957d
の上に、branch_b
の変更が乗っかる
* a27055b (HEAD -> refs/heads/branch_b) Add 'c' in b.txt * 7d45f1d Add b.txt * ac7957d (refs/heads/master) Add 'd' in a.txt * 3d940b6 Add 'b' in a.txt * 26ba7e0 Add a.txt
上のような状態を fast-forward な関係にある という
git rebase --interactive
つかいみち : コミットの履歴を編集する
* afe1290 (HEAD -> refs/heads/make_01_txt) Add 'aaa' on 01.txt * cccfaee Add 01.txt * 183848b (refs/heads/master) first commit
git rebase -i 183848b
commit番号より上のcommitについて、 git rebase --interactive
を行う
pick cccfaee Add 01.txt pick afe1290 Add 'aaa' on 01.txt # Rebase 183848b..afe1290 onto 183848b (2 command(s)) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
- pick commitを採用
- reword 名前変更
- squash 上のcommitと合体
- fixup 上のcommitと合体(commitメッセージは捨てる)
こうする
reword cccfaee Add 01.txt fixup afe1290 Add 'aaa' on 01.txt
- この場合、 9f6ec01 は、上のcommitと合体
- その上で、79f2ab0 のコミットメッセージを変更
すると、commitメッセージの変更画面が出るので変更する
* 4625879 (HEAD -> refs/heads/make_01_txt) Create 01.txt * 183848b (refs/heads/master) first commit
すっきりした!
ちなみに
git rebase --interactive
の時に、commitの順序の入れ替えもできるので便利です
git rebase のログを見る
git reflog
4625879 HEAD@{0}: rebase -i (finish): returning to refs/heads/make_01_txt 4625879 HEAD@{1}: rebase -i (fixup): Create 01.txt 4cdf15a HEAD@{2}: rebase -i (reword): Create 01.txt cccfaee HEAD@{3}: cherry-pick: fast-forward 183848b HEAD@{4}: rebase -i (start): checkout 183848b afe1290 HEAD@{5}: commit: Add 'aaa' on 01.txt cccfaee HEAD@{6}: commit: Add 01.txt 183848b HEAD@{7}: checkout: moving from master to make_01_txt 183848b HEAD@{8}: commit (initial): first commit
git rebase を元に戻したい!!
HEAD@{0}〜HEAD@{4} までが、git rebase でやったこと
git reset --hard HEAD@{5}
直前の git rebase
を戻したいのであれば
git reset --hard ORIG_HEAD
mergeやreset、rebase を行った直前の HEAD (べんり!!!!!!)
git merge
ブランチ make_01_txt
を master
にマージする
* afe1290 (HEAD -> refs/heads/make_01_txt) Add 'aaa' on 01.txt * cccfaee Add 01.txt * 183848b (refs/heads/master) first commit
git merge --ff
fast-forward な関係ならば、マージコミット無しでマージする
git merge make_01_txt --ff
* afe1290 (HEAD -> refs/heads/master, refs/heads/make_01_txt) Add 'aaa' on 01.txt * cccfaee Add 01.txt * 183848b first commit
fast-forward な関係じゃない場合は?
* e838a79 (HEAD -> refs/heads/master) Add 02.txt | * afe1290 (refs/heads/make_01_txt) Add 'aaa' on 01.txt | * cccfaee Add 01.txt |/ * 183848b first commit
マージコミットが作られる
* 33cd880 (HEAD -> refs/heads/master) Merge branch 'make_01_txt' |\ | * afe1290 (refs/heads/make_01_txt) Add 'aaa' on 01.txt | * cccfaee Add 01.txt * | e838a79 Add 02.txt |/ * 183848b first commit
git merge --no-ff
fast-forward な関係でも、マージコミットを作る
git merge make_01_txt --no-ff
* 4084ea5 (HEAD -> refs/heads/master) Merge branch 'make_01_txt' |\ | * afe1290 (refs/heads/make_01_txt) Add 'aaa' on 01.txt | * cccfaee Add 01.txt |/ * 183848b first commit
それぞれどういう時に使うの?
この辺はプロジェクト毎のルール次第のような
- ブランチをマージする時には、コミットを1個にsquashしてからマージするとか
- 必ず、マージコミットを作る為に
--no-ff
をつけるとか
git cherry-pick
特定のcommitをカレントブランチの先頭に乗っける
こんな場合
* ac7957d (HEAD -> refs/heads/master) Add 'd' in a.txt | * 9aa15f9 (refs/heads/branch_b) Add 'c' in b.txt | * b129f6c Add b.txt |/ * 3d940b6 Add 'b' in a.txt * 26ba7e0 Add a.txt
branch_b
の 9aa15f9
を、master
の HEAD
にのせる
git checkout master git cherry-pick b129f6c
* f16c177 (HEAD -> refs/heads/master) Add b.txt * ac7957d Add 'd' in a.txt | * 9aa15f9 (refs/heads/branch_b) Add 'c' in b.txt | * b129f6c Add b.txt |/ * 3d940b6 Add 'b' in a.txt * 26ba7e0 Add a.txt
参考
- git/git rebaseを元に戻す方法 - TOBY SOFT wiki
- 初心者でもわかる!リベースの使い方を解説します | Git編:一歩踏み出すフロントエンド入門
- 図で分かるgit-mergeの--ff, --no-ff, --squashの違い - アジャイルSEを目指すブログ
次回予告
git pull --rebase
を理解する
(おまけ)
本記事の git log は以下のオプションで出力してます
git log --graph --oneline --branches --decorate=full
エイリアスにしておくと便利かも