LoginSignup
37
30

More than 3 years have passed since last update.

一目置かれるコミット運用

Last updated at Posted at 2020-12-17

綺麗なコミットを心がける

TL;DR

コードレビューを依頼する立場からgitのコミットログを見やすくするための2つのテクニック

(1つ目) コミットをまとめる

1. データが消えないように小まめにコミットする

様々な開発環境によってリアルタイムに保存されているから予期せぬ事態が発生してもデータが飛ぶことがないということもあるかも知れませんが、安全第一に考えて出来る限りコミットする。

作業が終わっていなくても以下のタイミングでコミットする

  • 休憩前
  • ランチなどの食事前
  • 1日の作業を終えて帰宅する前

コミットのタイトルに[WIP]をつける

  • 作業が終わっていないけどコミットする際にはコミットログのタイトルに[WIP]をつける

2. コミットをまとめる

作業が完了したらgit logコマンドを実行し、コミットを確認する。
[WIP]がついているコミットがある場合コミットをまとめます。

2-1. コミットログを確認する

↓上の方が新しいコミットです。下に行くほど昔のコミットです。

コミットログ
$ git log --oneline

611dc15 (HEAD -> master) [WIP] Add test code
8cfe213 [WIP] Add parameter
3c53778 Add main.swift
870eb78 Register project files.

上記のコミットログのうち[WIP]がついている上から2つコミットをまとめる

  • [WIP] Add test code
  • [WIP] Add parameter
2-2. git rebaseを使う

2つのコミットをまとめるために以下のコマンドを実行する
git rebase -i HEAD~2
実行すると下記のように表示されます。
*git logの場合は降順(上の方が新しい)で表示されますが、git rebaseの場合は昇順(下の方が新しい)で表示されるので注意が必要です。pick 611dc15 [WIP] Add test codeの方が新しいコミット

rebaseコマンド実行後に表示される
pick 8cfe213 [WIP] Add parameter
pick 611dc15 [WIP] Add test code

# Rebase 3c53778..611dc15 onto 3c53778 (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.
#
# Note that empty commits are commented out
2-3. コミットを編集する
編集前
pick 8cfe213 [WIP] Add parameter
pick 611dc15 [WIP] Add test code

↑を↓に書き換えます(2行目のpicksに変更)

編集後
pick 8cfe213 [WIP] Add parameter
s 611dc15 [WIP] Add test code
編集後(全文)
pick 8cfe213 [WIP] Add parameter
s 611dc15 [WIP] Add test code

# Rebase 3c53778..611dc15 onto 3c53778 (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.
#
# Note that empty commits are commented out

編集完了後に:wqで決定する。

2-4. コミットメッセージを編集する
コミット編集時の表示
# This is a combination of 2 commits.
# This is the 1st commit message:

[WIP] Add parameter

main.swiftファイルに変数を追加。

# This is the commit message #2:

[WIP] Add test code

main.swiftファイルにテストコードを追加しました。

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Dec 15 15:32:14 2020 +0900
#
# interactive rebase in progress; onto 3c53778
# Last commands done (2 commands done):
#    pick 8cfe213 [WIP] Add parameter
#    squash 611dc15 [WIP] Add test code
# No commands remaining.
# You are currently rebasing branch 'feature/#1_Create_main_file' on '3c53778'.
#
# Changes to be committed:
#       modified:   main.swift
#
# Untracked files:
#       hoge.txt
#

編集する部分は以下

編集箇所
# This is a combination of 2 commits.
# This is the 1st commit message:

[WIP] Add parameter

main.swiftファイルに変数を追加。

# This is the commit message #2:

[WIP] Add test code

main.swiftファイルにテストコードを追加しました。
編集後
Add needed functions for main.swift

main.swiftファイルに必要なファイルを全て実装しました。
編集後全文
Add needed functions for main.swift

main.swiftファイルに必要なファイルを全て実装しました。

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Dec 15 15:32:14 2020 +0900
#
# interactive rebase in progress; onto 3c53778
# Last commands done (2 commands done):
#    pick 8cfe213 [WIP] Add parameter
#    squash 611dc15 [WIP] Add test code
# No commands remaining.
# You are currently rebasing branch 'feature/#1_Create_main_file' on '3c53778'.
#
# Changes to be committed:
#       modified:   main.swift
#
# Untracked files:
#       hoge.txt
#

編集完了後に:wqで決定する。

編集後のコミットログ
$ git log --oneline

6f6c506 (HEAD -> master) Add needed functions for main.swift
3c53778 Add main.swift
870eb78 Register project files.

コミットをまとめる前とまとめた後のコミットログの比較は以下です。

611dc15 (HEAD -> master) [WIP] Add test code
8cfe213 [WIP] Add parameter
3c53778 Add main.swift
870eb78 Register project files.
6f6c506 (HEAD -> master) Add needed functions for main.swift
3c53778 Add main.swift
870eb78 Register project files.

*最新のコミットAdd needed functions for main.swiftのコミットID(ハッシュ)が新たに作成されています => 6f6c506

3. リモートリポジトリへ登録する

コミットを編集する前と編集した後ではコミットのIDが変わってしまっているためそのままgit pushするとエラーが発生します。そこでpushに-fオプションをつけます。強制プッシュとなりますのでmastermaindevelopブランチでコミットを編集して強制プッシュはしないようにしましょう。チーム開発をしている場合は特に。

$ git push -u -f origin 作業ブランチ名

(2つ目)マージコミットを作らない

チームで開発では各メンバーはfeatureブランチで作業を行なっているかと思います。誰かがPull requestを完了させてdevelopブランチにマージされると他のメンバーはdevelopにマージされた情報を自分の作業ブランチであるfeatureブランチにマージする必要があります。
そこでfeatureブランチにdevelopをマージすると以下のようなマージコミットが作成されます。
Merge branch 'develop' into feature/自分の作業ブランチ
自分の作業したコミット以外にマージコミットができるのでコミットログが増えてしまいます

そこでコミットログが増えないようにするために利用できるのがrebaseです。
rebaseはコミットをまとめるでも出てきたように多機能なコマンドです。
ここではマージコミットを作らないようにするための機能を紹介いたします。

まず通常のマージとリベースとの違いを比較いたします。

マージ

あるキャラクターを作成する作業フローを図式しました。
AさんとBさんの2人でキャラクターを作成しています。
よくあるgit-flowでの開発フローです。
Aさんの作業が先に終わってdevelopにマージされました。
そこでBさんはdevelopが更新されたのでBさんが作業しているブランチにdevelopの情報をマージしました。
すると赤枠になっているマージコミットが作成されます。

git-pull-rebase.001.png

Bさんの作業は「耳の作成」「口の作成」「目と鼻の作成」の3つですがマージコミットが入ってきたので4コミットになっています。自分で作業していないコミットが一つ入ってきてしまっています。

git-pull-rebase.002.png

マージコミットが1つだけなので然程気にならないかも知れませんがもっと大人数で開発している場合はマージコミットがどんどん増えていきます。後から見返すにもコミットログが多くなってしまって他のブランチを含めてコミットログが見にくくなってしまいます。

そこでマージコミットを残さないやり方をしてみます。リベースの登場です。

リベース

まずは以下のgitのコミットログ画像を参照ください。

git-pull-rebase.003.png

マージコミットがなく自分で作業したコミットのみになっています。
自分の作業ブランチのコミット数はdevelopをマージした場合は4つ、リベースした場合はコミットが3つとなっています。

どうやってマージコミットを残さないようにするかについて図説致します。

  1. developが更新される
    git-pull-rebase.004.png

  2. git pull --rebase origin developコマンド実行
    git-pull-rebase.005.png

  3. git pull --rebase origin developコマンド完了後
    git-pull-rebase.006.png

Aさんが更新した顔の色を塗った変更がマージされたdevelopブランチが新たな起点となってBさんの変更が開始されています。

最後に比較です。
左がdevelopの変更をmergeしたもの、右がdevelopの変更をpull --rebaseしたものです。
image.png

まとめ

  1. コミットをまとめる
  2. マージコミットを残さない

この2つを実践して自分の作業ブランチのコミットログを綺麗に保ってみましょう。
レビュワーの方が気づいて「できるな!」と思われるかも知れません。
「余計なことするな」と言われる可能性もあるので事前に確認することで「できるな!」と思ってくれるかも知れませんので一度試してみてはいかがでしょうか。

37
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
30