プログラミング初学者なしこの技術アウトプット

プログラミングスクールRUNTEQで学んだことや自習したことのアウトプットをするブログ

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されてしまうので注意。(マージコミットが履歴から消える)

上記の注意点について説明します。
  1. 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~○とした方が安全ということを学びました!