Skip to content

もっとGitを使いこなすための応用編(後編)

公開日:December 12, 2024更新日:December 12, 2024
Git📄

前編では、cherry-pickcommit --amendstashtagreflog、エイリアス設定など、Git の応用的な使い方を学びました。この後編では、さらに強力なコマンド rebase -i をマスターしましょう!

コミットをまとめよう(git rebase -i

git rebase -i は、複数のコミットをまとめたり、順番を入れ替えたり、コミットメッセージを修正したりすることができる、非常に強力なコマンドです。-i は「対話的(interactive)」なリベースを意味します。

どんなときに使うの?

git rebase -i は、主に以下のような場合に使います。

  • 複数の細かいコミットを、1つのまとまったコミットにしたい。
  • コミットの順番を入れ替えて、変更履歴をわかりやすくしたい。
  • 過去のコミットメッセージを、より適切に修正したい。
  • 不要なコミットを削除したい。

具体的な使用例と手順

ここでは、以下のコミット履歴を例に、git rebase -i の使い方を説明します。

* 9b2f8a1 (HEAD -> new-feature) Fix typo
* e5f7a3b Add details to new feature
* d4c8b2a Add new feature
* c7b4e5f Initial commit

このコミット履歴で、Fix typoAdd details to new featureAdd new feature の3つのコミットを、Add new feature and fix typo という一つのコミットにまとめてみましょう。

  1. rebase -i の実行: まとめたいコミットの範囲を指定して、git rebase -i コマンドを実行します。ここでは、c7b4e5f のコミットは残して、それ以降の3つのコミットをまとめるために、以下のように実行します。

    bash
    git rebase -i c7b4e5f

    このコマンドを実行すると、エディタが開き、以下のような内容が表示されます。

    pick d4c8b2a Add new feature
    pick e5f7a3b Add details to new feature
    pick 9b2f8a1 Fix typo
    
    # Rebase c7b4e5f..9b2f8a1 onto c7b4e5f (3 commands)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
    #                    commit's log message, unless -C is used, in which case
    #                    keep only this commit's message; -c is same as -C but
    #                    opens the editor
    # x, exec <command> = run command (the rest of the line) using shell
    # b, break = stop here (continue rebase later with 'git rebase --continue')
    # d, drop <commit> = remove commit
    # l, label <label> = label current HEAD with a name
    # t, reset <label> = reset HEAD to a label
    # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
    # .       create a merge commit using the original merge commit's
    # .       message (or the oneline, if no original merge commit was
    # .       specified); use -c <commit> to reword the commit message
    #
    # These lines can be re-ordered; they are executed from top to bottom.
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    #
    # However, if you remove everything, the rebase will be aborted.
    #
  2. コマンドの編集: エディタに表示された各行が、1つのコミットに対応しています。各行の先頭には、そのコミットに対して行う操作(コマンド)を指定します。

    今回は、d4c8b2a Add new feature のコミットはそのままに(pick)、e5f7a3b Add details to new feature9b2f8a1 Fix typo のコミットを一つ前のコミットにまとめる(squash)ように編集します。

    pick d4c8b2a Add new feature
    squash e5f7a3b Add details to new feature
    squash 9b2f8a1 Fix typo

    エディタで上記のように修正したら、ファイルを保存してエディタを終了します。

    squashを指定されたコミットは、その上のpickされたコミットにまとめられます。 この例では、e5f7a3b Add details to new feature9b2f8a1 Fix typoのコミットが、d4c8b2a Add new featureのコミットにまとめられることになります。

  3. コミットメッセージの編集: エディタを閉じると、再度エディタが開き、新しいコミットメッセージを編集するように求められます。デフォルトでは、まとめられるコミットのメッセージがすべて連結された状態になっています。

    # This is a combination of 3 commits.
    # This is the 1st commit message:
    
    Add new feature
    
    # This is the commit message #2:
    
    Add details to new feature
    
    # This is the commit message #3:
    
    Fix typo

    不要なメッセージを削除し、新しいコミットメッセージを編集します。

    Add new feature and fix typo
    
    This commit adds a new feature and fixes a typo.

    ファイルを保存してエディタを終了すると、リベースが実行され、コミットがまとめられます。

  4. 結果の確認:git log コマンドで、コミット履歴が変更されたことを確認しましょう。

    bash
    git log --oneline
    * a1b2c3d (HEAD -> new-feature) Add new feature and fix typo
    * c7b4e5f Initial commit

    Add new featureAdd details to new featureFix typo の3つのコミットが、Add new feature and fix typo という一つのコミットにまとめられました!

注意点

git rebase -i は、コミット履歴を改変する 強力なコマンドです。そのため、以下の点に注意して使用する必要があります。

  • リモートリポジトリにプッシュしたコミットに対しては、rebase -i を使わない。 他の人がそのコミットを元に作業している場合、混乱を招く可能性があります。
  • rebase -i を使う前に、必ずブランチのバックアップを取っておく。 何か問題が発生した場合に、元の状態に戻せるようにしておくと安心です。
    bash
    git branch backup-new-feature
  • コンフリクトが発生する可能性がある。rebase -i を実行すると、途中でコンフリクトが発生する可能性があります。その場合は、「2.6 ブランチで実験しよう」で学んだコンフリクトの解決方法を参考に、手動でコンフリクトを解消する必要があります。