概要
どうも、@daiki1003です!先日、 @riscaitさんが
Gitに関する興味深いアンケートを行っていました。
プルリクエストでマージ先(例えばfeatureブランチから見たdevelopブランチ)の更新を取り込みたいとき、どうしてますか?
— 村松龍之介@FlutterとFirebaseでアプリ作る人 (@riscait) April 25, 2021
皆さんはどれに当てはまりましたか?
僕個人としては、強くrebase
を推し進めたいです。
本記事では、
・rebase
することによるメリット・デメリット
について書いていこうと思います。
もし、意見があればぜひ@daiki1003までお気軽にお願いします!
僕もいろんなプロジェクトに参画させていただく中でこの手の話は
結構しているのでちょうど良い機会だなと思っています。
それでは行ってみましょう!
※記事を読みやすくするためにrebase
自体の説明は
割愛させていただきます。
rebaseのメリット
コミット履歴を汚さない
個人的にはこれが一番大きい理由です。
下記スクショは、develop
ブランチを
マージした場合とrebase
した場合を順番に表示しています。
どちらの方が見やすいかは言うまでもないですよね?
non fast-forward
なマージをすれば、最初のスクショの様にマージコミットが出来てしまいます。
10回develop
ブランチに追従しようと思えば
何の意味も産まないコミットが10コミットも出来てしまいます。
Fork
やSourceTree
などのGitクライアントを使って
作業している方は多くいると思います。
あるブランチで、どんな変更が加わっているかを見たいと思った中で
上記画像の様に線が何重にも折り重なっていて見やすい人って多分いないと思います。(いたらすみません。)
最新の状態を保ちやすい
上記「コミット履歴を汚さない」に付随する様な話でもあるのですが、rebase
はその痕跡をGitのログ上には残しません。
なので、こまめにdevelop
ブランチの変更を取り込みやすいです。
最新のdevelop
ブランチで開発するということは
図らずも他の人が開発した内容をデバッグすることにもなりますし、
変更内容が自分に関係ある場合はより早く取り込む必要があるのでrebase
を使ってこまめに取り込みましょう。
そこにデメリットはありません。
また、rebase
をせずにマージをした以下の例をご覧ください。
ログイン周りがちゃんとテストされたか不安になりませんか?
それがrebase
後のマージであればこうです。
安心感が段違いですね。
その代わり、ちゃんとテストはしてくださいね?笑
各コミットが最新のdevelopからの変更を意味する
言いたいことを一言にまとめるのには苦労するので例を出しますね。
こんな状態だったとします。
開発ブランチでもdevelop
ブランチでも “A” を足してしまっています。
これをマージすると、レポジトリ上に 「”A”を追加する」と言う同じ意味を持ったコミットが複数存在することになります。
果たしてこれは意味があるのでしょうか?
rebaseだと、これはどうなるかと言うと
となり、 “A” の追加コミットがfeature
ブランチからはなくなります。
「くっそー、俺の作業が無駄になったじゃねぇか…」
と思う人以外はこちらの方が嬉しいのではないでしょうか?
また、上記画像はシンプルにするために
影響範囲が一つのコミット一つのファイルでおさまっていますが、
実務上では、より影響は大きくなって来るはずです。
コンフリクトをコミット毎に直せる
develop
ブランチの変更を取り込む際、往々にしてコンフリクトが起こることはあるでしょう。
でも、コンフリクトを直すこと自体は楽しい作業ではないので
出来るだけ楽に済ませたいはずです。
マージは、開発ブランチ全ての変更に対してdevelop
を一気にマージする
形になるのでコンフリクト解消が基本的に大変になりがちです。
それに対して、rebase
の場合、
一つ一つのコミットに対してコンフリクトが起こればその修正を行っていく形になります。
もし、コミットを意味のある範囲で出来る限り小さく収めていれば
コンフリクトはすごく楽に解消出来るはずです。
補足
※個人的に「コンフリクト解消」と言うコミットが一番嫌いです笑
コンフリクト解消が難しいと思ったら、以下の手順を試してみてください。
1. 自分が変更した内容を一度捨てる
2. その状態から、自分が初めて実装するとしたらどう変更するかを考える
3. それを実装し、コミットする
これが頭に入っていれば「コンフリクト解消」などというコミットは一生しなくて済むはずです 💪
また、慣れてくれば 「1. 自分が変更した内容を一度捨てる」は実際にやらなくても大丈夫になってきます。
コンフリクトしている内容を見て、
「develop
のコードから、rebase対象のコミット内容を初めて実装するとしたらどう変更するか」
と言う視点で解消していけるはずです!
rebaseのデメリット
さて、ここまでrebase
のメリットを挙げましたが
デメリットが全くないかと言われるとそんな事はありません。
が、僕個人としてはそこまで気にならないし気にしなくて良いものだと思っています。
コミッター(及びハッシュ)が変わってしまう
Gitのコミットには、2つの著者情報があります。Author
とCommiter
です。
Author
は、オリジナルのコードを書いた人Commiter
は、そのコミットをした人
【参考】
です。
rebase
はその名の通り、コミットのbaseつまり親コミットを変更し、再コミットをします。
ここで、上にも書いたようにCommiter
はコミットをした人になるので
rebaseをした人に書き換えられてしまいます。
中には、ここに抵抗を感じる方もいます。
さらに、コミッターや親コミットを元にコミットのハッシュは計算されているので
ハッシュも変わります。
GitHubなどでレビューをしている最中にrebase
を行ってしまうと
少し見づらくなるので注意が必要です。
CIが再度始動してしまう
ほとんどの実務用レポジトリでは、GitHub ActionsなどでCIを利用していると思います。
その設定によっては、rebase
後のforce pushによって
再度CIが動きます。
ですが、これは必要なチェックだと個人的には思っています。
rebase
をしたと言うことは、プログラム全体としても
変わっていることに他ならないのでCIは再度動かすべきですよね?
最後に
いかがでしたでしょうか?rebase
は上手く付き合えば将来の自分や
同じレポジトリを開発する仲間を大いに救ってくれるものなのでぜひ
チャレンジしてみてください!
ただ、サーバーサイドのレポジトリなど
相性が悪いレポジトリなんかもあったりするので必ずしも全ての
レポジトリで使えるわけではないかもしれません。
Twitterフォローお願いします
「次回以降も記事を読んでみたい!」「この辺分からなかったから質問したい!」
そんな時は、是非Twitter (@daiki1003)やInstagram (@ashdik_flutter)のフォローお願いします♪
Twitterコミュニティ参加お願いします
Twitterコミュニティ「Flutter lovers」を開設しました!参加お待ちしております😁
☕️ Buy me a coffee
また、記事がとても役に立ったと思う人はコーヒーを奢っていただけると非常に嬉しいです!
コメント