git rebaseの注意点とgit rebase -i -p Head~○コマンドについて
Gitについて以下の動画で復習をしました!
https://www.udemy.com/course/unscared_git/learn/lecture/6680208#content
有料でしたがとてもわかりやすく、全体を一気に復習できるのでおすすめです。
Gitがどのようなデータ構造で、裏でどのように動いているのかも含め解説してくれたので、コマンドを覚えたり使い慣れるだけでなく、このコマンド裏で何が起こっているかがわかるようになりGitを扱う際の恐怖心が減りました。
ここで自分が少し難しいなと感じたgit rebaseについて、いくつか注意点を書いていきます。
※rebaseコマンドとは変更を取り込む際に履歴を一直線に綺麗に整えるために使うコマンド
※mergeコマンドと似ているが、mergeは取り込んだ際にマージコミットを新規作成する
rebaseの注意点
* GitHubにプッシュ済のコミットをrebaseするのはNG!
→プッシュ済のコミットをrebase(新しいコミットIDが付与される)すると次プッシュする際にGitHub(リモートリポジトリ)とローカルとの間の履歴が異なるのでプッシュできなくなる。
* git push -fは絶対NG
→強制的(force)にプッシュはGitHubの履歴が壊れてしまうのでダメ
* プッシュしていないローカルの変更にはrebaseを使い、プッシュした後はmergeを使うようにする
* 複数のコミットをやり直すときgit rebase -i Head~○を使うとマージコミットが表示されないので表示する場合git rebase -i -p Head~○と打つ
→マージコミットが存在する場合「-p」を入れないとGitのエディタ上にマージコミットが表示されず、マージコミット抜きでrebaseされてしまうので注意。(マージコミットが履歴から消える)
上記の注意点について説明します。
- masterブランチからfeatureブランチを作成しfeature1.htmlファイルを作成しコミット。
#featureブランチ % git log --oneline aa2a0f9 (HEAD -> feature) feature1.htmlを新規作成 78165e5 (origin/master, master) initial commit
2.masterブランチに切り替え、master1.htmlファイルを作成しコミット。
※つまりmasterとfeatureブランチで枝分かれして作業している状態にする。
#masterブランチ % git log --oneline 3c7902e (HEAD -> master) master1.htmlを新規作成 78165e5 (origin/master) initial commit
3. masterブランチでfeatureブランチの変更をgit merge feature
で取り込むとマージコミット(Merge branch 'feature')が作成される。
#masterブランチ % git log --oneline b6c0614 (HEAD -> master) Merge branch 'feature' 3c7902e master1.htmlを新規作成 aa2a0f9 (feature) feature1.htmlを新規作成 78165e5 (origin/master) initial commit
4. masterブランチで
* git rebase -i -p Head~2
とした場合 Gitのエディタが立ち上がり以下のように表示される。
pick 3c7902e master1.htmlを新規作成 pick aa2a0f9 feature1.htmlを新規作成 pick b6c0614 Merge branch 'feature'
この場合Merge branch 'feature'というマージコミットも含まれているので、何も変更せずGitのエディタを閉じれば問題なく終了でき、変更履歴(git log)も変わらない。
* git rebase -i Head~2
とした場合以下のように表示される。
pick 3c7902e master1.htmlを新規作成 pick aa2a0f9 feature1.htmlを新規作成
この場合Merge branch 'feature'というマージコミットが含まれていないのでGitのエディタを閉じるとマージコミット無しの状態でリベースされてしまう為、以下のように変更履歴(git log)からマージコミットが消えてしまうので注意!!
% git log --oneline 28bb459 (HEAD -> master) feature1.htmlを新規作成 3c7902e master1.htmlを新規作成 78165e5 (origin/master) initial commit
最初、自分はマージコミットが含まれている状態でGitHubにプッシュした直後にgit rebase -i Head~X
してしまった為(上記の注意点でNGと記載)、ローカルのマージコミットが消えていたらしく、それに気づかず次の作業後にプッシュしようとした際にリモートとローカルの履歴に差が生じた(ローカルからマージコミットが消失)のでプッシュできないと怒られました。。
このことから、(1)GitHubにプッシュ済のコミットをrebaseするのはNG
、(2)マージコミットがある場合には基本的にはgit rebase -i -p Head~○とした方が安全
ということを学びました!