Git リベース: 知っておくべきことすべて
公開: 2022-12-15 Git rebase
コマンドは、2 つのソース コード ブランチを 1 つに結合します。 Git merge
コマンドもそれを行います。 rebase
の機能、使用方法、および代わりにmerge
を使用する場合について説明します。
Git 爆発
Git マージとは
Git リベースとは
別のブランチにリベースする方法
Git Rebase vs. Merge: どちらを使うべきか?
リベースするかリベースしないか?
Git 爆発
Linux カーネルで有名な Linus Torvalds は、他のバージョン管理システムとその遅い更新とコミットに不満を感じ、2005 年に 1 か月を費やして独自のバージョンを作成しました。 彼はそれを Git と名付けました。
GitHub、GitLab、BitBucket などのサイトは、共生的に Git を促進し、Git から恩恵を受けています。 今日、Git は世界中で使用されており、2022 年の調査では 71,000 人の回答者の 98% が Git をバージョン管理システムとして使用しています。
Git の主な設計上の決定事項の 1 つは速度でした。 特に、ブランチでの作業は可能な限り高速である必要がありました。 ブランチは、バージョン管理システムの基本的な部分です。 プロジェクト リポジトリには、メインまたはマスター ブランチがあります。 これは、プロジェクトのコード ベースが存在する場所です。 新機能などの開発は、分離されたサイド ブランチで行われます。 これにより、ブランチで行われた作業がマスター ブランチを台無しにするのを防ぎ、コード ベースのさまざまな部分で同時開発を行うことができます。
サイド ブランチでの開発が完了すると、開発ブランチをマスター ブランチにマージすることにより、変更がマスター ブランチに転送されます。 他のバージョン管理システムでは、ブランチを操作するのは難しく、計算コストがかかりました。 Git でのブランチの操作は非常に高速で、非常に軽量です。 かつては面倒で、他のシステムでは避けることが多かった作業が、Git では些細なことになりました。
Git rebase
コマンドは、あるブランチから別のブランチに変更を転送する別の方法です。 merge
コマンドとrebase
コマンドの目的は似ていますが、異なる方法で目的を達成し、わずかに異なる結果が得られます。
Git マージとは
では、Git merge
コマンドは何のためにあるのでしょうか。 新しい機能に取り組むためにdev-branch
というブランチを作成したとしましょう。
いくつかのコミットを行い、新しい機能をテストします。 それはすべてうまくいきます。 ここで、新しい機能をmaster
ブランチに送信します。 別のブランチをマージするには、 master
ブランチにいる必要があります。
マージする前に明示的にチェックアウトすることで、 master
ブランチにいることを確認できます。
git チェックアウト マスター
Git にdev-branch
をmaster
ブランチである current ブランチにマージするように指示できるようになりました。
gitマージ開発ブランチ
merge
が完了しました。 master
ブランチをチェックアウトしてコンパイルすると、新しく開発された機能が含まれます。 Git が実際に実行したのは、3 者間マージです。 master
ブランチとdev-branch
ブランチの最新のコミットと、 dev-branch
が作成される直前のmaster
ブランチのコミットを比較します。 次に、 master
ブランチでコミットを実行します。
マージは、何も削除せず、Git 履歴を変更しないため、非破壊的であると見なされます。 dev-branch
はまだ存在しており、以前のコミットは変更されていません。 3 方向マージの結果をキャプチャする新しいコミットが作成されます。
マージ後、Git リポジトリはタイムラインのように見え、別のラインが分岐してからメイン タイムラインに戻ります。
dev-branch
ブランチがmaster
ブランチに組み込まれました。
1 つのプロジェクトに多数のブランチがある場合、プロジェクトの履歴が混乱する可能性があります。 これは、プロジェクトに多くの貢献者がいる場合によくあります。 開発作業はさまざまな経路に分かれるため、開発の歴史は直線的ではありません。 ブランチに独自のブランチがある場合、コミット履歴のもつれを解くことはさらに困難になります。
master
ブランチにコミットされていない変更がある場合は、何かをマージする前に、これらの変更を処理する必要があることに注意してください。 新しいブランチを作成し、そこに変更をコミットしてから、マージを行うことができます。 次に、一時ブランチをマスター ブランチにマージする必要があります。
それは機能しますが、Git には、新しいブランチを作成せずに同じことを実現するコマンドがあります。 stash
コマンドは、コミットされていない変更を保存し、 stash pop
でそれらを呼び出すことができます。
次のように使用します。
隠し場所 gitマージ開発ブランチ スタッシュ ポップ
最終結果はマージされたブランチであり、保存されていない変更が復元されます。
Git リベースとは
Git rebase
コマンドは、まったく異なる方法でその目的を達成します。 リベースしようとしているブランチからすべてのコミットを取得し、リベース先のブランチの最後にそれらをリプレイします。
前の例では、アクションを実行する前の Git リポジトリは次のようになっています。 dev-branch
というブランチがあり、それらの変更をmaster
ブランチに移動したいと考えています。
rebase
の後は、単一の完全に直線的な変更のタイムラインのように見えます。
dev-branch
が削除され、 dev-branch
のコミットが master ブランチに追加されました。 最終結果は、 dev-branch
のコミットが最初にmaster
ブランチに実際に直接コミットされた場合と同じです。 コミットはmaster
ブランチに追加されるだけでなく、「再生」されて新たに追加されます。
これが、 rebase
コマンドが破壊的であると見なされる理由です。 リベースされたブランチは別のブランチとして存在しなくなり、プロジェクトの Git 履歴が書き直されました。 後の時点で、どのコミットが最初にdev-branch
に対して行われたかを判断することはできません。
ただし、単純化された線形の履歴が残ります。 数十または数百ものブランチとマージがあるリポジトリと比較して、Git ログを読んだり、グラフィカルな git GUI を使用してリポジトリのグラフを表示したりすると、リベースされたリポジトリは簡単に理解できます。
別のブランチにリベースする方法
git rebase
の例を試してみましょう。 new-feature
というブランチを持つプロジェクトがあります。 このブランチをmaster
ブランチにrebase
します。
まず、 master
ブランチに未解決の変更がないことを確認します。
git ステータス
new-feature
ブランチをチェックアウトします。
git チェックアウトの新機能
現在のブランチを master ブランチにrebase
するように Git に指示します。
git リベース マスター
まだ 2 つのブランチがあることがわかります。
gitブランチ
master
ブランチに戻します
git チェックアウト マスター
new-feature ブランチを current ブランチ (この場合はmaster
ブランチ) にマージします。
git マージの新機能
興味深いことに、最終的なマージ後も 2 つのブランチが残っています。
違いは、 new-feature
ブランチのヘッドとmaster
ブランチのヘッドが同じコミットを指すように設定されていることnew-feature
。支店のラベル。
Git Rebase vs. Merge: どちらを使うべきか?
rebase
対merge
の場合ではありません。 どちらも強力なコマンドであり、おそらく両方を使用するでしょう。 とはいえ、 rebase
がうまく機能しないユースケースもあります。 merge
を使用したミスによる unpick ミスは不快ですが、 rebase
による unpick エラーは地獄です。
あなたがリポジトリを使用している唯一の開発者である場合、悲惨なrebase
を行う可能性は低くなります。 たとえば、間違った方向にrebase
し、マスター ブランチをnew-feature
ブランチにrebase
する可能性があります。 master
ブランチを元に戻すには、今度はnew-feature
ブランチからmaster
ブランチに再度rebase
する必要があります。 奇妙に見える履歴ではありますが、それはあなたのmaster
ブランチを復元します.
他の人が作業する可能性が高い共有ブランチでは、 rebase
を使用しないでください。 リベースされたコードをリモート リポジトリにプッシュすると、リポジトリへの変更によって多くの人に問題が発生します。
プロジェクトに複数の貢献者がいる場合、安全なのはローカルリポジトリでのみrebase
を使用し、パブリック ブランチでは使用しないことです。 同様に、プル リクエストがコード レビューの一部である場合は、 rebase
を使用しないでください。 または、少なくとも、プル リクエストの作成後にrebase
を使用しないでください。 他の開発者があなたのコミットを見ている可能性があります。つまり、それらの変更はmaster
ブランチになくても、パブリック ブランチにあるということです。
危険なのは、既にリモート リポジトリにプッシュされているコミットをrebase
しようとしている場合であり、他の開発者が既にそれらのコミットに基づいて作業している可能性があります。 ローカルのrebase
により、これらの既存のコミットが消滅します。 これらの変更をリポジトリにプッシュすると、人気がなくなります。
他の貢献者は、自分の作業をリポジトリに戻すために、面倒なmerge
を行う必要があります。 その後、変更をローカル リポジトリに戻すと、重複した変更の混乱を解消することに直面します。
リベースするかリベースしないか?
プロジェクトでRebase
が禁止されている可能性があります。 地域的、文化的な異論があるかもしれません。 一部のプロジェクトや組織は、 rebase
を一種の異端であり、冒涜行為と見なしています。 Git の履歴は、何が起こったかの不可侵の永続的な記録であるべきだと考える人もいます。 したがって、 rebase
は検討の対象外になる可能性があります。
ただし、プライベート ブランチでローカルに使用する場合、 rebase
は便利なツールです。
リベース後にプッシュし、開発者が自分だけのブランチに制限します。 または、少なくとも、すべての開発が停止し、他の誰もあなたのブランチのコミットに基づいて他の作業を行っていない場所。
そうすることで、問題を回避できます。
関連: Git のバージョンを確認して更新する方法