git rebase を怖れない
概要
これまで、git rebase
はマージコミットを残さないのでよくない(どこで問題が起きたかわからなくなる)。
という理由で無邪気にgit merge
していたが、
プルリクのサイズがでかくなると、ファイルの差分(変更点)だけでレビューするのがだいぶ苦しくなってくるなぁ。という壁にぶつかったのでgit rebase
コマンドを練習してみる
よくあるケース
コミット履歴を綺麗にする
とりあえずこんな感じのコミット作っといて実験してみよー
$ git log --oneline 7d95cfa (HEAD -> feature/from) fourth comment 4947e58 third comment fd622a7 second comment 6996fbe first comment a741ac4 add new line 0b34183 (origin/master, origin/HEAD, master, develop) Initial commit
コミットコメント書き換えたいなー
4つ分のコミットを対象にする
git rebase -i HEAD~4
vim画面が表示されたらpick
をr
に変更して:wq
で保存
pick 6996fbe first comment r fd622a7 second comment pick 4947e58 third comment r 7d95cfa fourth comment # Rebase a741ac4..7d95cfa onto a741ac4 (4 commands) # # 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
r
に変更した分だけvimが表示されるので変更したいコメントに変更&保存
2nd comment # Please enter the commit message for your changes. Lines starting
名前変わってる!
$ git log --oneline 25f8fb9 (HEAD -> feature/from) 4th comment 00f97ee third comment d36ca5b 2nd comment 6996fbe first comment a741ac4 add new line 0b34183 (origin/master, origin/HEAD, master, develop) Initial commit
コミットをまとめたい
順番入れ替えたり、s
でコミットを統合したりして見る
上のコミット(前のコミット)に統合される
pick 6996fbe first comment pick 25f8fb9 4th comment s d36ca5b 2nd comment pick 00f97ee third comment # Rebase a741ac4..25f8fb9 onto a741ac4 (4 commands)
リベース中に衝突起きちゃうとパニック
vim画面で:wq
保存すると。。。でた!このごちゃごちゃ言ってくるやつ
Auto-merging README.md CONFLICT (content): Merge conflict in README.md error: could not apply 25f8fb9... 4th comment Resolve all conflicts manually, mark them as resolved with "git add/rm <conflicted_files>", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply 25f8fb9... 4th comment
とりあえずgit status
して見るのだ
$ git status [feature/from|rebase-i] interactive rebase in progress; onto a741ac4 Last commands done (2 commands done): pick 6996fbe first comment pick 25f8fb9 4th comment Next commands to do (2 remaining commands): squash d36ca5b 2nd comment pick 00f97ee third comment (use "git rebase --edit-todo" to view and edit) You are currently rebasing branch 'feature/from' on 'a741ac4'. (fix conflicts and then run "git rebase --continue") (use "git rebase --skip" to skip this patch) (use "git rebase --abort" to check out the original branch) Unmerged paths: (use "git reset HEAD <file>..." to unstage) (use "git add <file>..." to mark resolution) both modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
git rebase --abort
するともとに戻せる。これまではパニックになってこれで逃げてた気がするw
git diff
打ってみると、うむぅ。やはりコンフリクトしてる。直して見よう。
$ git diff ++<<<<<<< HEAD +azcdefghijklmnopqrstu ++======= + awcdefghijklmnopqrstu ++>>>>>>> 25f8fb9... 4th comment
git rebase --continue
しろって言ってたなぁ。。
$ git rebase --continue README.md: needs merge You must edit all merge conflicts and then mark them as resolved using git add
怒られた。git addするのね。。
$ git add README.md $ git rebase --continue [detached HEAD 8e03aea] new 2nd comment 1 file changed, 1 insertion(+), 1 deletion(-) Auto-merging README.md CONFLICT (content): Merge conflict in README.md error: could not apply d36ca5b... 2nd comment Resolve all conflicts manually, mark them as resolved with "git add/rm <conflicted_files>", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply d36ca5b... 2nd comment
まだ出る!!!これぶつかり続けてる限り出るのねきっと
$ git log --oneline fc3b535 (HEAD -> feature/from) third comment 40b3699 new 3nd comment 6996fbe first comment a741ac4 add new line 0b34183 (origin/master, origin/HEAD, master, develop) Initial commit
conflictしてるものを直し続けたら ちょっと意図した通りにはならなかったけど、順番変わってくっついた!!
間違って埋め込んだ修正を直したい
修正したいコミットのpick
をe
に変更して保存
$ # third commentのコミットを変更したい $ git log --oneline 7d95cfa (HEAD -> feature/from) fourth comment 4947e58 third comment fd622a7 second comment 6996fbe first comment a741ac4 add new line 0b34183 (origin/master, origin/HEAD, master, develop) Initial commit $ git show 4947e58 -aycdefghijklmnopqrstu +axcdefghijklmnopqrstu $ $ # 恒例のrebase -i $ git rebase -i HEAD~4 pick a741ac4 add new line pick 6996fbe first comment e 40b3699 new 3nd comment pick fc3b535 third comment # Rebase 0b34183..fc3b535 onto 0b34183 (4 commands)
あとは修正したいファイルを修正してgit add && git rebase --continue
すればよろしく変更される!
$ git log --oneline 091a7c4 (HEAD -> feature/from) fourth comment e2411bb third comment fd622a7 second comment 6996fbe first comment a741ac4 add new line $ $ git show e2411bb -aycdefghijklmnopqrstu +alcdefghijklmnopqrstu
途中のコミット変更したことでconflictしちゃうこともあるけど、上で書いた通り解消してgit add && git rebase --continue
しとけばよろしく変わってる
リモートにプッシュしたけどrebaseして綺麗にしたい!!!
共同で開発してるブランチじゃやっちゃいけないだろうけど。
自分専用で開発してるブランチを綺麗にしたい時とかにしたい。
$ git log --oneline 091a7c4 (HEAD -> feature/from, origin/feature/from) fourth comment e2411bb third comment fd622a7 second comment 6996fbe first comment a741ac4 add new line 0b34183 (origin/master, origin/HEAD, master, develop) Initial commit $ $ git rebase -i HEAD~4 [detached HEAD 04e3b85] 3rd comment Date: Tue Jan 1 09:45:00 2019 +0900 1 file changed, 1 insertion(+), 1 deletion(-) Successfully rebased and updated refs/heads/feature/from. $ $ git branch -vv develop 0b34183 Initial commit * feature/from 011984f [origin/feature/from: ahead 2, behind 2] fourth comment master 0b34183 [origin/master] Initial commit $ $ git push origin [feature/from] To ssh://github.com/shintaro123/practice_docker.git ! [rejected] feature/from -> feature/from (non-fast-forward) error: failed to push some refs to 'ssh://git@github.com/shintaro123/practice_docker.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 push origin -f Counting objects: 6, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (6/6), 564 bytes | 564.00 KiB/s, done. Total 6 (delta 0), reused 0 (delta 0) To ssh://github.com/shintaro123/practice_docker.git + 091a7c4...011984f feature/from -> feature/from (forced update) $ $ git log --oneline 011984f (HEAD -> feature/from, origin/feature/from) fourth comment 04e3b85 3rd comment fd622a7 second comment 6996fbe first comment a741ac4 add new line 0b34183 (origin/master, origin/HEAD, master, develop) Initial commit
rebaseするとコミット自体作り変えてしまうので、push時に怒られちゃう。
なので-fつけるとよろし
ブランチの派生元間違えてた
間違えてブランチ派生させてたら、付け替えれる
$ git log --graph --all * commit 1daf0829120078db7e1e21703b3dee3e9489824c (HEAD -> feature/1) | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 11:54:32 2019 +0900 | | 6th comment | * commit 7ce16217a2626ae5de96ff3c679a5cf61a996061 | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 11:52:53 2019 +0900 | | 5th comment | * commit 011984f0d0b69c23ee5c49daeae60a21b60021f8 (origin/feature/from, feature/from) | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 09:50:37 2019 +0900 | | fourth comment | * commit 6996fbe6155a4646581a1a755e0d4994ac2857fa | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 09:43:41 2019 +0900 | | first comment | * commit a741ac4af34810b19c5b803488242789d634dead | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 09:42:30 2019 +0900 | | add new line | * commit 0b34183461640d118a4cb92cb1a0ad810da34844 (origin/master, origin/HEAD, master, develop) Author: Shintaro <shintaro.0112@gmail.com> Date: Mon Dec 31 21:22:03 2018 +0900 Initial commit $ $ git rebase --onto develop feature/from feature/1 First, rewinding head to replay your work on top of it... Applying: 5th comment Using index info to reconstruct a base tree... M README.md Falling back to patching base and 3-way merge... Auto-merging README.md CONFLICT (content): Merge conflict in README.md error: Failed to merge in the changes. Patch failed at 0001 5th comment Use 'git am --show-current-patch' to see the failed patch Resolve all conflicts manually, mark them as resolved with "git add/rm <conflicted_files>", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". $ $ # conflictしたら直してgit rebase --continue $ git log --graph --all * commit 9791e34f9ff11b58f517835f0db36f72eb150ddc (HEAD -> feature/1) | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 11:54:32 2019 +0900 | | 6th comment | * commit 69e9a35f0978b6cad234f2fb8150b2df2638a268 | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 11:52:53 2019 +0900 | | 5th comment | | * commit 011984f0d0b69c23ee5c49daeae60a21b60021f8 (origin/feature/from, feature/from) | | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | | Date: Tue Jan 1 09:50:37 2019 +0900 | | | | fourth comment | | | * commit a741ac4af34810b19c5b803488242789d634dead |/ Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 09:42:30 2019 +0900 | | add new line | * commit 0b34183461640d118a4cb92cb1a0ad810da34844 (origin/master, origin/HEAD, master, develop) Author: Shintaro <shintaro.0112@gmail.com> Date: Mon Dec 31 21:22:03 2018 +0900 Initial commit
もう何もわからない。もとに戻したい
git reflog
コマンドを使うと操作履歴が出るので、色々間違っちゃってもこれを頼りにgit reset --har [コミット番号]
でもとに戻せる
$ git reflog 9791e34 (HEAD -> feature/1) HEAD@{0}: rebase finished: returning to refs/heads/feature/1 9791e34 (HEAD -> feature/1) HEAD@{1}: rebase: 6th comment 69e9a35 HEAD@{2}: rebase: 5th comment 0b34183 (origin/master, origin/HEAD, master, develop) HEAD@{3}: rebase: checkout develop 1daf082 HEAD@{4}: commit: 6th comment 7ce1621 HEAD@{5}: commit: 5th comment 011984f (origin/feature/from, feature/from) HEAD@{6}: checkout: moving from feature/from to feature/1 011984f (origin/feature/from, feature/from) HEAD@{7}: rebase -i (finish): returning to refs/heads/feature/from 011984f (origin/feature/from, feature/from) HEAD@{8}: rebase -i (pick): fourth comment $ $ git log --graph --all [feature/1] * commit 1daf0829120078db7e1e21703b3dee3e9489824c (HEAD -> feature/1) | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 11:54:32 2019 +0900 | | 6th comment | * commit 7ce16217a2626ae5de96ff3c679a5cf61a996061 | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 11:52:53 2019 +0900 | | 5th comment | * commit 011984f0d0b69c23ee5c49daeae60a21b60021f8 (origin/feature/from, feature/from) | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 09:50:37 2019 +0900 | | fourth comment | * commit 6996fbe6155a4646581a1a755e0d4994ac2857fa | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 09:43:41 2019 +0900 | | first comment | * commit a741ac4af34810b19c5b803488242789d634dead | Author: Shintaro Uchiyama <shintaro.a.uchiyama@accenture.com> | Date: Tue Jan 1 09:42:30 2019 +0900 | | add new line | * commit 0b34183461640d118a4cb92cb1a0ad810da34844 (origin/master, origin/HEAD, master, develop) Author: Shintaro <shintaro.0112@gmail.com> Date: Mon Dec 31 21:22:03 2018 +0900 Initial commit
派生元の付け替えもなかったことに!!!!!
まとめ
ちょろっと書こうとしたら多くなった。
やはり一度コマンド打つとしっくりくる。これからは実際の開発でもちゃんと使っていこう!!!!