Tips > 履歴の書き換え
git rebase -i コマンドを利用すると、
過去にコミットした履歴を簡単に書き換えることができます。
以下、具体例を用いて説明します。
# 履歴の書き換えというのは、分散型SCMならではの機能ですね。(^^)
過去にコミットした履歴を簡単に書き換えることができます。
以下、具体例を用いて説明します。
# 履歴の書き換えというのは、分散型SCMならではの機能ですね。(^^)
更新例:
a -> b -> c -> d -> e -> f (a, b, c, … はそれぞれコミットを指します)
履歴を精査した結果、次のように書き換える必要が
あることがわかったとします。
あることがわかったとします。
- b のコメントが間違っているので訂正
- c と d は1つに纏めた方が良い (例えば d は c の修正の誤字を修正しているのみとか・・)
- e と f は順番を逆にした方が分かりやすい
これら修正をして、最終的に以下の状態にします。
a -> b' -> (c,d) -> f -> e
手順:
1) git log コマンドにて、各コミットのコミットIDを確認
$ git log --pretty=oneline | tac | tail -20 a8c78c640990ec19acfac2e23c4f13d545102d08 GHSRC-SFCM-xxxx:ファイル a を追加 98e2e5177295afc29b3efcc1b46b4203fe7ec69c GHSRC-SFCM-xxxx:ファイル b を追加 71bf1c9a4b0f99d23dd5e3840febd340955f6034 GHSRC-SFCM-xxxx:ファイル c を追加 001b967de5bfbdd2bb0fa74ae5df66620cf1210c GHSRC-SFCM-xxxx:ファイル d を追加 a4c4670fb0b94f61f8e761a64de24467d67168c3 GHSRC-SFCM-xxxx:ファイル e を追加 260ab529ee2aa8197b9f1bb9623fa36de7ed1583 GHSRC-SFCM-xxxx:ファイル f を追加
-> 今回は a の位置から修正するので、
a のコミットID a8c78c640990ec19acfac2e23c4f13d545102d08 をメモする
a のコミットID a8c78c640990ec19acfac2e23c4f13d545102d08 をメモする
2) 変更前のコミット位置にタグを付け、バックアップします。
$ git tag GHSRC-SFCM-xxxx.backup
3) git rebase -i コマンドを実行
$ git rebase -i a8c78c64099 → 変更指示書ファイル(git-rebase-todo)が生成され、vi にて 以下の情報が表示されます。 pick 98e2e51 GHSRC-SFCM-xxxx:ファイル b を追加 pick 71bf1c9 GHSRC-SFCM-xxxx:ファイル c を追加 pick 001b967 GHSRC-SFCM-xxxx:ファイル d を追加 pick a4c4670 GHSRC-SFCM-xxxx:ファイル e を追加 pick 260ab52 GHSRC-SFCM-xxxx:ファイル f を追加 (「#」で始まる説明文は省略しています)
4) 以下のように変更します。
- b のコメントが間違っているので訂正
→ b の行頭を「pick」→「edit」に変更します。
- c と d は1つに纏めた方が良い
→ d の行頭を「pick」→「squash」に変更します。
(squash は押しつぶすという意味)
(squash は押しつぶすという意味)
- e と f は順番を逆にした方が分かりやすい
→ e を f の後ろに移動。
修正後イメージは以下のとおりです。
edit 98e2e51 GHSRC-SFCM-xxxx:ファイル b を追加 pick 71bf1c9 GHSRC-SFCM-xxxx:ファイル c を追加 squash 001b967 GHSRC-SFCM-xxxx:ファイル d を追加 pick 260ab52 GHSRC-SFCM-xxxx:ファイル f を追加 pick a4c4670 GHSRC-SFCM-xxxx:ファイル e を追加
5)「:wq」によりviを終了。
以下のようなメッセージが表示されます。
以下のようなメッセージが表示されます。
".git/rebase-merge/git-rebase-todo" 16L, 577C 書込み Stopped at 98e2e51... GHSRC-SFCM-xxxx:ファイル b を追加 You can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue
「GHSRC-SFCM-xxxx:ファイル b を追加」の履歴のところで
rebase が STOP し、コミット履歴を書き換えられる状態となっていることを示しています。
また、git commit --amend でコミットを訂正し、終わったら git rebase --continue してねと言っています。
このメッセージにあるとおり、移行で更新作業をします。
rebase が STOP し、コミット履歴を書き換えられる状態となっていることを示しています。
また、git commit --amend でコミットを訂正し、終わったら git rebase --continue してねと言っています。
このメッセージにあるとおり、移行で更新作業をします。
6) b の履歴を訂正:
git commit --amend コマンドを実行し、
コミットコメントを修正します。
(または、git gui を起動し「最新コミットを訂正」より訂正することも可能)
~
修正が完了したら git rebase --continue を実行します。
→ 次の履歴変更の位置でまた STOP します。
git commit --amend コマンドを実行し、
コミットコメントを修正します。
(または、git gui を起動し「最新コミットを訂正」より訂正することも可能)
~
修正が完了したら git rebase --continue を実行します。
→ 次の履歴変更の位置でまた STOP します。
7) c と d は1つに纏める:
1つに纏める場合、統合後のコミットメッセージを
どうするか決めなくてはいけません。
その為、vi が起動し、コミット編集状態になります。
1つに纏める場合、統合後のコミットメッセージを
どうするか決めなくてはいけません。
その為、vi が起動し、コミット編集状態になります。
---------------------------------------- # This is a combination of two commits. # The first commit's message is: GHSRC-SFCM-xxxx:ファイル c を追加 # This is the 2nd commit message: GHSRC-SFCM-xxxx:ファイル d を追加 ---------------------------------------- コミットメッセージを更新して「:wq」でviを終了します。 (なお、「#」で始まる行は無視されるので、 いちいち消さなくてもOKです)
→ vi を終了すると、自動的に 次の履歴書き換えに進みます。
8) e と f は順番を逆に:
並び替えをしてもコンフリクト(競合)がおきない場合は、 自動的に並び替えをしてくれます。
9) git log を実行し、訂正結果を確認します。
$ git log --pretty=oneline | tac | tail -20 a8c78c640990ec19acfac2e23c4f13d545102d08 GHSRC-SFCM-xxxx:ファイル a を追加 1554bba93a444b74e99e839efe567a8abc63aa07 GHSRC-SFCM-xxxx:ファイル b を追加 (訂正) 0909a4699be995316807f6d062afdeb703186c2d GHSRC-SFCM-xxxx:ファイル c,d を追加 4833d5bb200149b857f118e0e7d4ac84caaa9f51 GHSRC-SFCM-xxxx:ファイル f を追加 adb0727346e685f765a8ba7fa15d5fedc21e2cbe GHSRC-SFCM-xxxx:ファイル e を追加
10) 問題なければ、バックアップ用に作成していたタグを削除します。
$ git tag -D GHSRC-SFCM-xxxx
なお、作業にて問題がおきた場合は、
いつでも「git rebase --abort」によって元の状態に
戻ることができます。~
いつでも「git rebase --abort」によって元の状態に
戻ることができます。~