Help us understand the problem. What is going on with this article?

git rebaseを初めて使った際のまとめ

More than 1 year has passed since last update.

環境

とくになし

はじめに

今までrebaseを使ったことが無かったのですが、コードレビューを依頼した際に「マージコミットが邪魔で見づらい…」と言われてしましました。「ログを綺麗にするため」にrebaseについて学んだことのまとめです。
まず、ログがどのように綺麗になるのかを以下に説明します。

mergeを使った場合のログ(あまり綺麗ではないログ)

例えば下図のようなブランチが存在し、自分が今featureにいるとします。この状況でbugfixが入った最新のdevelopを取り込みたいと考えているとします。
スクリーンショット 2017-07-29 11.23.48.png
マージを使って取り込みます。
スクリーンショット 2017-07-29 11.26.35.png
無事取り込むことができました。しかし「git log」をしてみると時系列順に並ぶためfeatureのコミットが飛び飛びになってしまい、すごく見づらくなっています。
スクリーンショット 2017-07-29 11.29.35.png

rebaseを使った場合のログ

最初の状況は先程と同じです。
スクリーンショット 2017-07-29 11.23.48.png
rebaseを使って取り込んでみましょう。
スクリーンショット 2017-07-29 11.32.32.png
無事取り込むことができました。ログを見ると綺麗にまとまっています。
スクリーンショット 2017-07-29 11.34.19.png
これならレビューもしやすい!

先にまとめ

# featureブランチで以下を行う
# mergeと違って作業ブランチにて行うので注意

# まずコミットをまとめる
git rebase -i 派生元コミット

# rebaseを行う
git rebase develop

解説

git rebaseが行っていること

新しい派生元に1つずつcherry-pickしているイメージです。

# featureブランチにて
git rebase develop

スクリーンショット 2017-07-29 11.43.35.png
「A''」がコンフリクトしなければ続けて「B''」...
スクリーンショット 2017-07-29 11.43.49.png
というような処理が全コミット分行われます。気をつけるべきは履歴が書き換わってしまうことです。
rebase後のコミットも「A''」や「B''」と表記していますが、コミットハッシュが変わってしまっているので、全くの別コミットになります。
既にpush済なら「-f」をつけないとpushできません。しかし、これは他の人に影響を及ぼす危険な操作なので決して人が利用しているブランチに同意も取らずに行ってはいけません。
http://qiita.com/ppworks/items/94c0107d98e55f903ea9

rebaseの途中でコンフリクトしたら...

スクリーンショット 2017-07-30 10.40.49.png
途中でrebaseが止まり、解決を促すメッセージが表示されます。

$ git rebase develop
First, rewinding head to replay your work on top of it...
Applying: List化
Using index info to reconstruct a base tree...
M   git.txt
Falling back to patching base and 3-way merge...
Auto-merging git.txt
CONFLICT (content): Merge conflict in git.txt
Failed to merge in the changes.
Patch failed at 0001 List化
The copy of the patch that failed is found in:
   /Users/ma-sato/Documents/gitSample/.git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

メッセージの下の方に書いていますが、選択肢は「続ける」「飛ばす」「止める」の3つあります。
「飛ばす」に関しては使う場面に遭遇したことが無いので、「続ける」と「止める」についてだけ解説します。

「続ける」場合

git rebase --continue

コンフリクトを解決し、対象のファイルがaddされているのを確認した後に上記を実行します。commitする代わりに実行する感覚です。引き続きrebaseが実行されます。
スクリーンショット 2017-07-30 10.43.38.png

「止める」場合

git rebase --abort

rebaseを行う前の状態に戻します。途中まで行っていたrebaseが全て無かったことになります。
スクリーンショット 2017-07-30 10.45.44.png

先にコミットをまとめる

git rebase -i 派生元コミット

rebaseは1コミットずつ作業を行っていくので同じような箇所を何度も修正したコミットがあった場合、連続でコンフリクトが発生して、かなり面倒です。そこで先にコミットまとめておきます。下図のイメージになるようまとめてみます。
スクリーンショット 2017-07-30 10.56.59.png

$ git rebase -i 4dbbac3

pick b72d8f5 List化   # A'' に該当
s 96ff85c 説明追加    # B'' に該当
s 5d7361a インデント追加  # C'' に該当

# Rebase 4dbbac3..5d7361a onto 4dbbac3 (3 command(s))
#
# 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
#
# 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

まとめたいコミットの先頭の「pick」を「s」に変えた後に「:wq」で保存して編集を終わります。
すると次はコミットメッセージを編集する画面が立ち上がります。

# This is a combination of 3 commits.
# The first commit's message is:
List化

# This is the 2nd commit message:

説明追加

# This is the 3rd commit message:

インデント追加

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Jul 30 11:23:28 2017 +0900
#
# rebase in progress; onto 4dbbac3
# You are currently editing a commit while rebasing branch 'develop' on '4dbbac3'.
#
# Changes to be committed:
#       modified:   git.txt
#

squashした全コミット文のメッセージが並んでいるので適したメッセージをつけて再び「:wq」で保存して編集を終わります。
今回は1コミットにまとめてしまっていますが、あくまでログが見やすくなるように適宜まとめていきます。

このあとにrebaseすればコンフリクトの解決も必要最低限で済むので楽ちんです。
スクリーンショット 2017-07-30 10.59.38.png

さいごに

最低限使うにあたって必要なことをまとめました。まだまだ触れていないオプションがあるので、触り次第まとめていきたいです。

▽追記:d(drop)を使った際のお話
https://qiita.com/panti310/items/0af4de5378a1ea4af4d7

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away