コンサルでデータサイエンティスト

仕事でPythonを書いてます。機械学習、Webマーケティングに興味があります。趣味は旅です。

git rebase -i コマンドで複数のコミットを1つにまとめる

一度commitしたブランチに対してレビュー修正が入り再度コミットする必要がある場合など、複数のコミットを1つにまとめたい時がありますよね。そんなときに便利なgit rebase -i コマンドをご紹介します。

git rebase -i コマンドを使う場面

具体例を使って手順を確認していきましょう。fix api function というコミットでmerge request を出したものの、レビューでバグを指摘されたために修正コミット fix bug を出したという例を考えます。このようにMerge requestの出すまでの流れについては、次の記事にまとめてありますのでご確認ください。

hktech.hatenablog.com


このような場面でfix api function と fix bug という2つのコミットがログに残したままにしてしまうと、あとでチームメンバーが振り返ったときに何が行われていたのかわからなくなることがあります。また、チームやOSSによっては1 request 1 commitといったルールが採用されている場合もあります。そこで、複数のコミットを1つにまとめてくれる git rebase -iコマンドを使います。この -i とは -interactiveの略となっています。

git rebaseコマンドでコミットをまとめる手順

まずは、git log でgitの歴史を確認します。

git log


fix api function と fix bug というメッセージのコミットが2つあることを確認できます。

commit *****
Author: hktech
Date:   Thu Sep 27 20:58:09 2018 +0900

    fix api function

commit ******
Author: hktech
Date:   Wed Sep 19 14:19:37 2018 +0900

    fix bug


ここからいよいよ git rebase -i コマンドを使っていきます。
上から2つのコミットを1つにまとめたい場合、次のコマンドを打ちます。

git rebase -i HEAD~2 


これは、最新のコミットであるHEADから2つ目までを含めるということを表しています。
するとviなどのエディタで次のようなファイルが開きます。

pick t13rvfp fix api function
pick n2odp4q fix bug

#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# 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.
#


ファイルの文面には丁寧にコマンドの用法が記載されていますが、今回はこの中のpickとsquashを使っていきたいと思います。これらのコマンドはそれぞれ次のような意味を持ちます。

  • Pick (p): コミットをそのまま残す
  • Squash (s): コミットを前のコミットに統合する

今回はfix bugのコミットをfix api function に統合したいので、fix bug をpick から s(squash) に変更し、fix api functionはpickのまま残します。

pick t13rvfp fix api function
s n2odp4q fix bug


vi の場合は:wqで保存してファイルを抜けます。
ここで、再度git log をして変更を確認します。

git log


コミットが1つにまとまっていることが確認できました。

commit *****
Author: hktech
Date:   Thu Sep 27 20:58:09 2018 +0900

    fix api function
    fix bug


この状態で再度リモート(origin)にpushしてmergeをする準備をします。

git push origin fix-api-function


おそらくここで前コミットと競合してしまうため、前のコミットを上書きする形で強制的にpushを行います。このときに使う-f オプションは -forceを意味します。これはリモートレポジトリを強制的に変更してしまうため、使う際には注意が必要です。

git push -f origin fix-api-function

無事に複数のコミットをまとめることができました。

まとめ

git rebase -iコマンドで複数のコミットをまとめる方法についてご紹介しました。せっかくgitを運用するからにはログをキレイに整理しておきたいですよね。細かいコミットをたくさんしてしまっている方は、この記事を参考にコミットをまとめる習慣をつけてみてはいかがでしょうか。