インタラクティブリベースは、Gitの「スイスアーミーナイフ」と呼ばれることがあります – 多くの異なるツールを含み、多くの異なる使用例に対して使えるからです!インタラクティブリベースでGitの歴史をきれいに保つ方法について説明します。 しかし、1 つの主要で包括的な使用例があります。ローカル コミット履歴をクリーンアップすることです。 対照的に、リモートリポジトリに既にプッシュされ共有されているコミット履歴には使用すべきではありません。 Interactive rebase は Git の歴史を「書き換える」ツールのひとつで、すでに他の人と共有しているコミットに対してこれを行うべきではありません。
この小さな警告メッセージはさておき、いくつかの実践例を見ていきましょう。
注意: この投稿のシナリオとワークフローを簡単に視覚化するために、いくつかのスクリーンショットでは “Tower” Git Desktop GUI を使用しています。
古いコミット メッセージの修正
ときどき、古いコミット メッセージのタイプミスに気付くことがあります – あるいは、注目すべき記述に何かを書き忘れていることがあります。 もし私たちが直近のコミットについて話しているのであれば、単に git commit
コマンドの --amend
オプションを使用すればよかったのです。
A bad commit message that needs correction
対話的リベースセッションの最初のステップは、コミット履歴のどの部分を操作したいかを決定することです。
Starting our interactive rebase session
この開始コミットのハッシュを interactive rebase コマンドに渡します:
$ git rebase -i 0023cddd
今操作のためにあなたが選んだコミットのリストが入った編集ウィンドウが開くはずです。 対話的なリベースセッションでは、Git は古いコミットを次々に再適用します。つまり、順番を逆にすることは Git の観点からは正しいのです。 つまり、この具体例では、ここでコミットメッセージを変更することはありません。 その代わり、変更したいコミットをアクションキーワードでマークするだけです。 この例では、コミットメッセージを変更したいので、その行を “reword” とマークしています。 保存してこのエディターウィンドウを閉じると、古いコミットのメッセージを含む新しいエディターウィンドウが開かれます。
Finally, we can make our changes
もう一度保存して閉じると、対話型リベースセッションは完了し、古いコミットメッセージが修正されました。
Combining multiple commits into one
Another use case for interactive rebase is you want to combine multiple old comments into one. もちろん、バージョン管理の黄金律が適用されますが、ほとんどの状況で、いくつかの大きなコミットではなく、より多くの小さなコミットを作成することが有益です。 しかし、何事にも言えることですが、これをやりすぎて、二つ以上の古いコミットを一つにまとめたいと思うことがあります。
具体例を挙げると、以下の選択したコミットをひとつにまとめたいとします。
Let’s combine multiple commits into one
最初のケースと同様に、少なくとも操作したいものの親コミットから対話的リベース セッションを開始することにします。
$ git rebase -i 2b504bee
再び、エディターウィンドウが開き、操作したいコミット履歴の一部がリストアップされます。
Marking lines with “squash”
ここで使用するアクションキーワードは “squash” というものです。 そして、squashを使うために知っておくべき重要な情報が一つだけあります。”squash “キーワードでマークアップした行は、真上の行と結合されるのです。 上のスクリーンショットにあるように、2 番目の行を 1 番目の行と結合するために “squash” とマークしたのはそのためです。
ここで保存してエディターウィンドウを閉じると、再び新しいウィンドウが表示されます。
Entering a new message for the new, squashed commit
このウィンドウを保存して閉じると、古いコミットのチェンジセットを含む新しいコミットが作成されたことが確認できます。 ほらね!
間違いを修正する
対話的リベースのもうひとつの使用例は、以前のコミットのひとつに間違いを見つけたときです。 ある変更を追加するのを忘れたとか、ファイルを削除すべきだったとか、単にタイプミスをしたとか…
このような状況では、自然な傾向として、単にミスを修正する新しいコミットを作成することです。 しかし一方で、これはコミット履歴を混乱させます。オリジナルのコミットを作成し、いくつかのミスを修正するために「応急処置」のコミットを追加する…これは面倒な作業方法です。 コミット履歴はすぐに理解しづらくなり、すべての小さな「クイックフィックス」コミットで散乱してしまいます!
ここで、対話的リベースに付属するツールのひとつである「fixup」が非常に便利に使用できるようになります。 Fixup はこの「クイックフィックス」コミットを受け取り、その変更を元のコミットに適用し (それによって修正し)、そしてバンドエイドのコミットを取り除きます。 新しいファイルを追加する、既存のファイルを変更する、古いファイルを削除する……など、間違いを修正するための変更を「ただ」行う必要があるのです。
次のステップはこれらの変更をリポジトリにコミットすることです。しかし、ちょっとした追加をします。コミットするときに --fixup
フラグを使い、Git に悪いコミットのハッシュを知らせます。 しかし、よく見てみると、何かが起こっていることがわかります。新しいコミットの先頭に自動的に “fixup !” と悪いコミットの件名が追加されています。
The original commit and the fix commit
3番目のステップは、対話型のリベースセッションを始めるというものです。 ここでも、悪いコミットの親を開始点に選びます。
…そして秘密のソースの第二弾として、--autosquash
フラグを使用します。 このオプションは、今開いているエディタウィンドウで何もする必要がないことを確認するものです。 この状況をよく見てみましょう。
Our fix commit is marked “fixup” and sorted to the right position
The Git did automatically two things for us:
- It marked our band-aid commit as “fixup.” (応急処置のコミット).「
- 行の順序を変更し、バンドエイドのコミットがバッドコミットの直下に表示されるようにしたのです。
言い換えれば、保存してエディターウィンドウを閉じる以外、私たちにできることは何もありません。 しかし、その上、醜いバンドエイドのコミットはコミット履歴から消えました! まるで問題がなかったかのように、すべてがきれいになりました!
Discover the power of interactive rebase
対話的リベースにはたくさんの使用例があります – そしてそのほとんどは「間違いを直す」部門にあります。 これは、対話型リベースやその他の Git ツールを使って間違いを元に戻すことを学ぶのに役立つ短いビデオ (1話あたり2~3分) のコレクションです。 私のコミットのひとつに、GitLab ウェブサイトプロジェクトのルールに反する 1MB を超える画像が含まれていました。 そのコミットには正しいサイズの画像が含まれていたので、戻って修正する必要がありました。 universeさん、教えてくれてありがとうございます 😁
More Git tips and tricks
- 15 Git tips to improve your workflow
- How Git Partial Clone lets you fetch only the large file you need
- Git happens ! 6 つのよくある Git の間違いとその直し方
ゲスト執筆者について
Tobias Günther は Tower の CEO で、人気のある Git デスクトップ クライアントは、世界中の 10 万人以上の開発者が Git でより生産的になることを支援しています。
Cover image by David Taljat on Pexels