この記事の概要
今日現場で実際に使った、gitでpush済を取り消して
部分的な修正だけを取り込むcherry-pickの使い方を備忘録として記載しました
2020/03/06追記
この記事の手順について下記のご指摘を頂きました。
この手順だと、
Bさんの手元にあるリポジトリと、remoteのリポジトリ(Aさんがpush -fしたもの)が歴史が食い違うのでまたコンフリクトしてしまうはずです。
基本的にpush -fをすると、影響範囲が特定できなくなって事故の元ですので、どうしても回避できない時以外はやらない方が良いです。
https://next.rikunabi.com/journal/20180209_t12_iq/
push済のコミットを取り消す場合は、resetではなくてrevertを使うのが正攻法になります。
本当は commit -f で取り消すよりも
git revert
でコミットログ打ち消してから再度コミットが安全。
commit -f だとといくらでも過去の改ざんをできてしまう。
(今回は直前の作業で影響すくない&ゴミログ残したくなかったので commit -f使いました。)
前提
Aさんのコミット履歴
1回目のコミット コミット番号:00001
Aファイル更新
Bファイル更新
Cファイル更新
2回目のコミット コミット番号:00002
Dファイル更新
Eファイル更新
Fファイル更新
上記2つの修正はpush済
リモートブランチはA〜Fファイルが更新済の状態
※本来はコミット番号は下記の「ca82a6dff817ec66f44342007202690a93763949」のようなやつです
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon schacon@gee-mail.com
Date: Mon Mar 17 21:52:11 2008 -0700
BさんがAさんのFクラスの変更だけ取り込みたい場合
Aさんの作業
pushしたものをローカルで取り消す
→まずはコミット番号00001の状態にする
$ git reset --soft 00001
これでAさんのローカルの状態は、
00002の修正(D〜Fファイルの修正)が未コミット状態になる
※注)
$ git reset --hard 00001
を行った場合、Aさんのローカルは00002の修正(D〜Fファイルの修正)は存在しなくなる
この状態で、強制pushする
$ git push -f
これでリモートブランチが、00001の状態になる
(A〜Cファイルのみ更新状態)
次に、DとEファイルの更新のみをステージングしてコミット・pushする
→コミット番号:00003
次に、Fファイルの更新をステージングしてコミット・pushする
→コミット番号:00004
現在のリモートの状態
1回目のコミット コミット番号:00001
Aファイル更新
Bファイル更新
Cファイル更新
2回目のコミット コミット番号:00003
Dファイル更新
Eファイル更新
3回目のコミット コミット番号:00004
Fファイル更新
Bさんの作業
リモートの状態を取得
$ git fetch
Fファイルの修正分だけ取り込む
$ git cherry-pick 00004