複数のコミットを1つにまとめる方法

複数のコミットを1つにまとめる方法をサンプルレポジトリ共に紹介します。
2022.06.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

どうも。 えーたん(@eetann092)です。

先日公開したランチャーツールRaycastの使い方と設定 | DevelopersIO の執筆中にOSSへコントリビュートしました。 本記事では、コントリビュート時に気になって後から調べた「複数のコミットを1つにまとめる方法」を サンプルレポジトリのコードと共に紹介します。

コミットログをまとめる

コントリビュート時の注意事項がまとまっているCONTRIBUTING.mdを確認すると、コミットログをきれいにすることが求められていました。 たとえば、「コントリビュートする側がtypoした部分の修正をするためだけのコミット」は別のコミットにまとめる必要があります。

今回のコントリビュートの目的は「typoの修正」であったため関係はありませんでしたが、 本記事では好奇心でコミットの統合にトライしてみます。

まとめたいコミットの用意

以下がtypoした文章とします。

sample1: I love Kerrry.

コミットメッセージは"add sample1"とします。 Kerryrが1文字増えているtypoがあります。

次に、typoを修正します。 コミットメッセージは"fix typo"です。

sample1: I love Kerry.

ついでにもう少し編集します。 まとめるコミット(上記2つ)よりもあとにコミットした結果が、 コミットをまとめた後でも維持されることを確認するためです。

sample1: I love Kerry.
sample2: He is cool.

コミットメッセージは"add sample2"です。

各コミットは以下のGitHubのリンクから見ることができます。

コミットをまとめる

この時点でのコミットはgit log --onelineで確認できます。

1d1a084 (HEAD -> gattai, main) add sample2
0ca0ac8 fix typo
ff5b300 add sample1
0620d4c first commit

git rebaseを使い、add sample1fix typoadd sample1としてまとめます。 そのため、対象となるコミットは上3つです。

git rebase -i HEAD~3

テキストエディタが開きます。git logの表示では一番上が新しいコミットでしたが、 git rebaseのインタラクティブモードの表示では一番上は古いコミットになります。

指定した直近の3つのコミットが表示されます。 各コミットにどのような操作をするかをこのファイルに書き込んで指示します。

pick ff5b300 add sample1
pick 0ca0ac8 fix typo
pick 1d1a084 add sample2

# Rebase 0620d4c..1d1a084 onto 0620d4c (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.
#

今回はfix typoのコミットを前のコミットの中に含めたいため、2行目のpicksquashに書き換えます。

pick ff5b300 add sample1
squash 0ca0ac8 fix typo
pick 1d1a084 add sample2

# Rebase 0620d4c..1d1a084 onto 0620d4c (3 commands)
#
# Commands:
# 省略

編集を終了するとコミットメッセージ編集画面が表示されます。 元の2つのコミットメッセージとコメントアウトがずらりと並んでいます。

# This is a combination of 2 commits.
# This is the 1st commit message:

add sample1

# This is the commit message #2:

fix typo

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Thu Jun 9 09:12:25 2022 +0900
#
# interactive rebase in progress; onto 0620d4c
# Last commands done (2 commands done):
#    pick ff5b300 add sample1
#    squash 0ca0ac8 fix typo
# Next command to do (1 remaining command):
#    pick 1d1a084 add sample2
# You are currently rebasing branch 'gattai' on '0620d4c'.
#
# Changes to be committed:
#	modified:   sample.txt
#

今回はtypoしてしまったコミットのメッセージをそのまま使い、 typo修正のコミットメッセージは消します。

add sample1
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# 省略

コミットメッセージの編集を終了し、2つのコミットが1つになりました。 本当にできたのか、まずはgit log --onelineでコミットを確認します。

9524e62 (HEAD -> gattai) add sample2
d353f75 add sample1
0620d4c first commit

以下が統合後のコミットです。

コミットがまとまっていることが分かります。 また、まとめたかったコミットよりも後にコミットしたadd sample2に影響が無いことも分かります。

どんなコントリビュートをしたか

どんなコントリビュートだったかについても一応書きます。 PythonのライブラリPillowPilllowにtypoされていたのを修正しただけです。

fix library name typo by eetann · Pull Request #729 · raycast/script-commands

手順については、以下の記事を参考にしました。

コントリビュート時の注意事項がまとまっているscript-commands/CONTRIBUTING.mdを読んでから作業し、プルリクを出しました。

リンク集

サンプルコードのGitHubのリンクは以下です。 mainブランチが統合前、gattaiブランチが統合後です。

参考