Git squashで複数のコミットを1つでまとめる

2020-12-16 hit count image

Git squashを使って複数のコミットを1つのコミットでまとめる方法について説明します。

概要

オープンソースへコミット(Commit)する時や会社のソースコードを修正する時、普通、1つの課題(Issue)を作って、その課題を基準にしてブランチを作ります。そして、このように作ったブランチへ修正内容をコミット(Commit)します。しかし、普通はコミット1つで全ての修正を反映することができないです。フロントサイドの修正コミット、サーバーサイドの修正コミット、テストコードのコミット、コードレビュー対応コミットなど、1つの課題を修正するため、様々なコミットが発生します。

このように生成された様々なコミットをマージ(Merge)してもいいですが、オープンソースや色んな人が一緒に作業する会社のソースコードの場合、コミット履歴が多くって、複雑になって、コミットの履歴を追跡することが難しくなります。

これを避けるため、このブログポストではGitのSquash機能について説明します。

Git Squash

Git Squashは複数のコミット履歴を1つのコミット履歴でまとめる時使います。

Git Log

まず、下記のコマンドを実行してコミットした履歴を確認します。

git log --pretty=oneline

そしたら、下記のような結果が見えます。

1f199b7353e40e3134572c9986837b1b4bfebd13 (HEAD -> squash-test) third commit
0118d468a770c2340bf6d4d47f10984c58ea382b second commit
b91e257ce42d5f501c7bc8242a0580b3c05ef462 first commit
db078dae819cfed46bc6e6ef8c962648f97c22da (origin/master, origin/develop, master, develop) Merge pull request #1 from dev-yakuza/rebase-and-squash
c6bd068ec0ea39ef98e135218dc19375e5d63a68 (origin/rebase-and-squash, rebase-and-squash) add rebase-and-squash
2d33cf05e6352b2fa7e8574d170032b34e3a8959 change master
405d0d71ed50429a169ece18cf984dfd64c088a9 add proejct

私は現在Masterブランチからsquash-testブランチを作ってfirst commit, second commit, third commitのコミットをした状態です。

1f199b7353e40e3134572c9986837b1b4bfebd13 (HEAD -> squash-test) third commit
0118d468a770c2340bf6d4d47f10984c58ea382b second commit
b91e257ce42d5f501c7bc8242a0580b3c05ef462 first commit

db078dae819cfed46bc6e6ef8c962648f97c22da (origin/master, origin/develop, master, develop) Merge pull request #1 from dev-yakuza/rebase-and-squash

Git Rebase

次は、GitのSquash機能でfirst commit, second commit, third commitのコミットを1つのコミットに作ってみます。Squash機能を使うためにはGitのRebaseを使う必要があります。

まず、Gitのログをもう一回確認して、

1f199b7353e40e3134572c9986837b1b4bfebd13 (HEAD -> squash-test) third commit
0118d468a770c2340bf6d4d47f10984c58ea382b second commit
b91e257ce42d5f501c7bc8242a0580b3c05ef462 first commit

# We will rebase on here!!!!!!!!
db078dae819cfed46bc6e6ef8c962648f97c22da (origin/master, origin/develop, master, develop) Merge pull request #1 from dev-yakuza/rebase-and-squash

3つのコミットを1つのコミットで作る予定なので、3つのコミットをする以前であるdb078dae819cfed46bc6e6ef8c962648f97c22daへRebaseをします。

Squashを使うため、下記のGitのRebaseコマンドを使ってRebaseをします。

git rebase -i db078dae819cfed46bc6e6ef8c962648f97c22da

ここで-iをオプションを使ってことを注目してください。-iオプションを使ってので、普通のRebaseとは違って、下記のような結果が見えます。

pick b91e257 first commit
pick 0118d46 second commit
pick 1f199b7 third commit

# Rebase db078da..1f199b7 onto db078da (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 <commit> = like "squash", but discard this commit's log messag

この画面はRebaseを使ってコミット以前の状態に戻るようにしてるが、現在と過去の間に残ってるコミットをどう処理するかをGitが親切に質問してくれる画面です。下に使えるCommandのリストもあります。私たちはここで、s, squashを使う予定です。

# s, squash <commit> = use commit, but meld into previous commit

このコミットにはfirst commitを残してsecond committhird commitをSquashしてみます。キーボードのiボタンを押して、修正できる状態に変更した後、下記のように修正します。

pick b91e257 first commit
s 0118d46 second commit
s 1f199b7 third commit

# Rebase db078da..1f199b7 onto db078da (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 <commit> = like "squash", but discard this commit's log messag

そしてキーボードのESCボタンを押して:wqを入力した後、Enterキーを押して変更した内容を保存します。変更が完了されたら下記のような画面が見えます。

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

first commit

# This is the commit message #2:

second commit

# This is the commit message #3:

third commit

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Mon Apr 20 14:42:26 2020 +0900
#
# interactive rebase in progress; onto db078da
# Last commands done (3 commands done):
#    squash 0118d46 second commit

この画面はGitがRebaseを使ってSquashをする予定だけど、以前作成したコミットメッセージをどうするか聞いてくれる画面です。Gitが全てのメッセージを1つの画面で見せています。キーボードのiボタンを押して、下記のように修正します。(メッセージは皆さんの環境に合わせて変更してください。)

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

Fix Squash Task

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

メッセージの作成が完了されたら、キーボードのESCボタンを押して:wqを入力して保存します。

また、git log --pretty=onelineでコミット履歴を確認すると、

099e6f606b3a46b98f0233d558eb07c143a3ec01 (HEAD -> squash-test) Fix Squash Task
db078dae819cfed46bc6e6ef8c962648f97c22da (origin/master, origin/develop, master, develop) Merge pull request #1 from dev-yakuza/rebase-and-squash

Rebase以前とは違って、コミットが1つしか表示されないことが確認できます。また、メッセージの内容も私たちがSquashする時、作成した内容が表示されることが確認できます。

Git Push

次は、このように1つにしたコミットをリモートリポジトリ(Remote Repository)へPushします。

git push origin squash-test

すでにコミットした内容をリモートリポジトリへPushしたことがある場合、下記のように-fオプションを使って強制的変更します。

git push origin squash-test -f

完了

これでGitのSquashを使ってたくさんのコミット履歴を1つのコミットに変更する方法について見てみました。明確にはGitのRebaseを使ってSquashを実行したと言いますね。今回のブログポストで使ってコマンドをまとめてみました。

git log --pretty=oneline
git rebase -i [Commit Number]
# Select to pick and squash
# Change commit log
git push origin [Branch] -f
# git push origin [Branch]

皆さんもSquashを使って綺麗なコミット履歴を残してみてください! 여러분도 Squash를 통해 예쁜 커밋 이력을 남겨보세요!

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts