gitロググラフを綺麗にするちょっとした技【基本編】


gitログは綺麗に

ロググラフがごちゃごちゃしていると、履歴を追う時に心が折れます

git flowで開発をしていると、分岐するのは仕方が無い時もあるのですが、明らかに必要ないのに分岐させている人をよく見ます。
チリも積もると全く読めない(読みたくない)グラフになってしまうので、必要ない分岐はさせないに越したことはありません。

頻繁に分岐が発生するパターン

チームで開発をしていると、「pushしようとしたら他の人が先にpushしていた」ということが頻繁に発生します。
まだgit経験が浅い人は、ここで分岐させてしまいます。

発生例

例えば、グラフがこの状態にあるとします。

commit2(f9b26f3)に対して、修正点をcommitして、pushしようとします。

(master)$ git add .
(master)$ git commit -m 'commit 4'
(master)$ git push origin master

しかし、他の人が先にpushしていたので、non-fast-forwardが発生してpushできませんでした。

pushしようとしてエラー
(master)$ git push origin master
To https://github.com/west-hiroaki/git-test.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/west-hiroaki/git-test.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

リモートを含めたヒストリはこうなっています。
commit3(d3dcdd3)が、他の人が先にpushした修正です。

この場合、pushするためにどういうアクションをとるべきでしょうか?

分岐させちゃうパターン

ここでpullすると、分岐してしまいます。

pullコマンド実行(コメント入力は省略)
(master)$ git pull origin master

pullするとマージされるので、当然ながらこうなります。

分岐させないパターン

rebaseすると、分岐が発生しません。

rebaseコマンド実行
(master)$ git fetch -p
(master)$ git rebase remotes/origin/master
First, rewinding head to replay your work on top of it...
Applying: commit 4

rebaseコマンドによって、指定されているremotes/origin/master のコミット(commit3:d3dcdd3)に対して、ローカルのコミット(commit4)を付け直すからです。
(コミットIDが、90129be から0c4c338 に変わっているところからも付け直していることが分かります)

画像を見て分かる通り、ロググラフが一直線になり、時系列もすっきりします。

ちなみに、rebaseする前にfetch をしないと、ローカルのremote情報が古いままの可能性があります。その場合、rebaseされませんので行っておいた方が無難です。

おまけ:pullしちゃった時の回避方法Tips

ここからはおまけです。

pushしてnon-fast-forward状態であることに気がつく前に、pullしてしまって、コメント入力画面になってしまったらどうすればいいでしょうか?

(master)$ git pull origin master

コメント入力画面
Merge branch 'master' of https://github.com/west-hiroaki/git-test

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

このまま:wq するとマージが完了するので、グラフが分岐してしまいます。

回避方法

結構最近まで読んでませんでしたが、ちゃんと下にコメントで方法が書いてありました。

Lines starting with '#' will be ignored, and an empty message aborts the commit.

全てをコメント状態にすればabort状態に出来るとのことなので、1行目をコメントにします。(自分は面倒くさいので1行目を消しちゃってますが)

コメント入力画面:1行目をコメントアウト
# Merge branch 'master' of https://github.com/west-hiroaki/git-test

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

そして:wq でエディタを抜けると、マージが中断された状態になっています。

(master|MERGING)$

後は、abortさせればOKです。

(master|MERGING)$ git merge --abort

そうするとpullする前の状態に戻りますので、rebaseすることが可能になります。

(master)$