Git
新卒エンジニア
1
どのような問題がありますか?

投稿日

更新日

git rebase -i コマンドはいいぞ

この記事は新卒1年目 Advent Calendar 2021の2日目です。

概要

先輩から教えていただいた git rebase -i コマンドが非常に便利で、日頃から多用しています。
仕事で実際にやったことのあるケースをもとに、自分の使い方をご紹介します。

この記事で扱うコマンドは、以下の3つです。

  • edit
  • reword
  • fixup

対象読者

この記事は、以下のような方を対象読者と想定しています。

  • git rebase -i を完全に理解したい方
  • gitを使った開発の経験が浅い方
  • 自分同様まだ開発の実務経験が浅い方

この記事の特徴

新卒1年目のアドカレで投稿する記事ということで、主に自分同様まだ実務経験の浅い方へ向けて書きました。
このコマンドを知らない頃の自分でも理解できるように、丁寧に書いてみたつもりです。
誰かの git rebase -i コマンドの理解を深めるお役に立てれば幸いです。

ケース別 git rebase -i

この記事では、以下3つのケースで git rebase -i をどう使うかをご紹介します。

  • 以前のコミットの内容を編集したい
  • 以前のコミットのコミットメッセージのみ変更したい
  • 複数のコミットをまとめたい

以前のコミットの内容を編集したい

実際にあったのは、以下のようなケースです。

  • 「あ、さっきのコミットに、この内容も含めたいな」
  • 「やべ、さっきのコミット、自分用のコメント残したままだった」

こんなときは edit を使います。

結論

  1. git rebase -i HEAD^
  2. pickedit に変更して保存
  3. 1つ前のコミットに戻るので、そこで編集する
  4. git add (1つ前のコミットに含めたいもの) + git commit --amend
  5. git rebase --continue

具体例

コミット: add hoge

hoge.txt
+ hoge
+ fuga

「hogeだけを入れたかったが、間違えてfugaも入れてしまった。fugaを消したい」

手順1. git rebase -i HEAD^

$ git rebase -i HEAD^

手順2. pickedit に変更して保存

- pick xxxxxxx add hoge
+ edit xxxxxxx add hoge

  # Rebase xxxxxx..xxxxxx onto xxxxxx (2 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 <commit> = like "squash", but discard this commit's log message
  # 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.
  #

手順3. 編集する

hoge.txt
  hoge
- fuga

手順4. git add + git commit --amend

$ git add hoge.txt
$ git commit --amend

手順5. git rebase --continue

$ git rebase --continue

これで完了です。

以前のコミットのコミットメッセージのみ変更したい

実際にあったのは、以下のようなケースです。

  • 「さっきのコミットメッセージ、やっぱり違う表現の方がいいか」
  • 「prefixを間違えてしまった、正しくせねば」

こんなときは reword を使います。

結論

  1. git rebase -i HEAD^
  2. pickreword に変更して保存
  3. コミットメッセージを変更して保存

具体例

コミット: add fuga

hoge.txt
+ hoge

「hogeを追加したのに、間違えて、fugaを追加したというコミットメッセージにしてしまった」

手順1. git rebase -i HEAD^

$ git rebase -i HEAD^

手順2. pickreword に変更して保存

- pick xxxxxxx add fuga
+ reword xxxxxxx add fuga

  # Rebase xxxxxx..xxxxxx onto xxxxxx (2 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 <commit> = like "squash", but discard this commit's log message
  # 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.
  #

手順3. コミットメッセージを変更して保存

- add fuga
+ add hoge

  # Please enter the commit message for your changes. Lines starting
  # with '#' will be ignored, and an empty message aborts the commit.
  #
  # Date:      xxxxxxxxxxxx
  #
  # interactive rebase in progress; onto xxxxxx
  # Last command done (1 command done):
  #    reword xxxxxx add fuga
  # No commands remaining.
  # You are currently editing a commit while rebasing branch 'xxxxxxx' on 'xxxxxx'.
  #
  # Changes to be committed:
  #       modified:   hoge.txt
  #

これで完了です。

複数のコミットをまとめたい

実際にあったのは、以下のようなケースです。

  • 「細かくコミットしすぎたな、ちゃんと意味のある単位でまとめたい」
  • 「ペア・モブプロやってて、ドライバーを交代するために無意味なコミット&プッシュをしまくった。作業が完了したので、PRを出すためキレイにまとめないとな」

こんなときは fixup を使います。

結論

  1. git rebase -i HEAD~2
  2. pickfixup に変更して保存

具体例

コミット1: add hoge

hoge.txt
+ hoge

コミット2: add hoge_spec

hoge_spec.txt
+ hoge test

「hogeのテスト追加は、hogeを追加したコミットにまとめて良さそうだ」

手順1. git rebase -i HEAD~2

$ git rebase -i HEAD~2

手順2. pickfixup に変更して保存

  pick xxxxxxx add hoge
- pick xxxxxxx add hoge_spec
+ fixup xxxxxxx add hoge_spec

  # Rebase xxxxxx..xxxxxx onto xxxxxx (2 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 <commit> = like "squash", but discard this commit's log message
  # 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.
  #

これで完了です。

コミット add hoge_spec の内容が add hoge に入ります。
なお、コミットメッセージは add hoge となります。

ちなみに fixup ではなく squash を使うと、コミットメッセージの編集もできます。

おわりに

git rebase -i コマンドは非常に便利です。
この中でも、今回ご紹介した edit , reword , fixup は特に便利なコマンドです。
まだ使ったことのない方は、ぜひ一度お試しで使っていただき、その便利さを知っていただきたいです。

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
yuya_yuzen
福岡の新卒Webエンジニア

コメント

リンクをコピー
このコメントを報告

👏

ちなみに

「あ、さっきのコミットに、この内容も含めたいな」
「やべ、さっきのコミット、自分用のコメント残したままだった」

上記のような単純に追加や削除であれば

git add .  // 追加 or 削除したファイルをstageへ上げる
git commit --amend --not-edit

で直前のコミットと融合できるのでおすすめです。

1
リンクをコピー
このコメントを報告

@shippokun 編集リクエストありがとうございます!
投稿前によく確認したつもりだったんですが、大事なところを間違えてましたw

内容とコマンドのギャップがあるので修正しました by shippokun 2021/12/02 20:58

1
どのような問題がありますか?
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
1
どのような問題がありますか?
ユーザー登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
ユーザー登録ログイン
ストックするカテゴリー