1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Weekend EngineerAdvent Calendar 2019

Day 13

Gitで複数のコミットをまとめる方法について2通り調べてみた

Last updated at Posted at 2019-12-25

rebaseでコミットをまとめる際、プチやらかし案件を引き起こしてしまいました。
「複数のコミットをまとめて反映するならpatchを使うと良い」とアドバイスを受けたのですが、ググってみたら、rebaseでまとめる方法が多く紹介されていました。
この2通りの方法の違いが分からず調べたので、自戒を込めて記録しようと思います。

そもそもの2通りの方法の概要

1. patchファイルを当てる方法

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

  • $ git diff -p <派生元ブランチ> <派生先ブランチ> > a.patch
    2ブランチ間の差分をpatchファイルとして出力します。
    ※patchファイル名は任意です
  • $ patch --dry-run -p1 < a.patch
    ドライラン(テスト実行)で差分ファイルを確認します。
  • $ patch -p1 < a.patch
    差分を確認後に実際に流し込むと、git addの手前の状態になります。
  • (+α)$ git diff <派生元ブランチ> <派生先ブランチ> | patch -p1
    このように、1行にまとめて一気に実行することもできます。

2. rebaseでまとめる方法

  • $ git rebase -i HEAD~(HEADから遡るコミット数)
    vimが立ち上がるので、コミットメッセージやコミットの並び等を編集・保存する。
  • $ git push -f origin <branch>
    強制プッシュは慎重に!!
  • ※rebase前のコミット履歴はpush済みで、rebase中にコンフリクトしたら次の手順を踏む。
    • $ git co --ours(--theirs)
      片方のブランチの変更のみを一気に適用できない場合は、地道に編集するしか無い...?
    • $ git add .
    • $ git rebase --continue(コンフリクト解消後にrebaseを続行する)
      →終わったら再度$ git push -f origin <branch>

参考サイト

rebaseで少々やらかした話

何を失敗したのか

(@個人ブランチ) $ git merge develop
$ git rebase -i HEAD~xx でコミットをまとめる
$ git push -f origin <branch>

上記の手順を踏みました。何が起こるでしょうか?
・・・本ケースのように、まとめようとするコミットの間に、自分以外の人によるコミットが入っている場合は$ git rebase -i HEAD~xxを使うのはまずかったのです。
$ git rebase -i HEAD~xxでまとめると、他の人のコミットも付け直します。
この際に自分のコミットとしてまとめてしまうので、自分がコミットしたことになってしまいます。
自分の分のコミットだけを先にまとめてからdevelopブランチをマージする必要がありました。
こちらを参照)

まとめ

全般

  • $ git push -f origin <branch>は慎重に!!
  • 自分のコミットが分散している&他人のコミット入りのブランチをrebaseすると、
    他人のコミットを自分のコミットとしてコミットし直してしまう。
  • patchファイルを当てる方法
    →個人ブランチのコミットログを改変するわけではないので、
    個人ブランチの更新分を一括でdevelopブランチに適用する場合にしか使えない
    =「個人ブランチにしかない差分を1つの差分としてまとめて抽出し、developブランチの先頭コミットにくっつける」イメージ
    ※この際、個人ブランチのコミットログは分散したままとなる。

対処法

  • (このケースに陥ったら)このままマージするとまずい。
    →もしやってしまった場合は、別のブランチ作り直す&自分の変更分をコミットから取り出すことで対処できる
  • $ git rebaseだと枝の付け根を切り替えるというイメージ。
  • 今回のように自分の変更が分散してしまっている場合:
    別ブランチで切り直して、自分の分だけcherry-pickするのが早いと思われる。
    →git操作をミスった際の尻拭いとして使える...
  • $ git resetも使えると、間違えても修正が楽になる。
    →オプションの--soft, --hard, --mixedも意識できるとなお良し
  • マージ相手のブランチにcheckout
    →他人のコミットを改ざんしてしまった個人ブランチをmerge
    →pushせずに$ git reset HEAD^で変更分だけ抽出することもできる
    (大量にコンフリクトする可能性はあるが・・・)
1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?