コンフリクト解消するときに競合したブランチの修正内容が反映されてしまう
手順
困ったこと
なぜ含まれるか、なぜ気づけないか
conflictの解消をGitHubから行うととしているが、別にGitHubで作業していることが原因ではない。
conflictの解消を行う作業として、ops/test_aにdev(マージ先)をマージしている。
※マージしに行く前に、相手の最新の状態を自分に取り込んでおいてマージする
この時に、devに既にマージされているops/test_bの情報が取り込まれてしまう
プルリクのFiles Changedにもdevとops/test_aにops/test_bに関する差分がないので、もちろん表示されず
仕組みを理解していないと思わぬものが混在してしまう
解決策
ひとまずの対応
プルリク main ← ops/test_aまでにこの事象に気づかず、ops/test_a、ops/test_bどちらも数回変更が加わり、devにプルリク&マージしていた。
revertしてもエラーになってうまくいかず、乏しいGItの知識と差し迫るリリース時間に焦り、以下のようにした。
- ops/test_aは諦める
- conflictの解消前(ops/test_aの変更をコミット&プッシュしたとき)のコミットでブランチ(ops/test_c)を切る
- ops/test_aで変更した内容をops/test_cに加える
- プルリク main ← ops/test_c
イケてないので、できればconflict解消後にすぐ修正しておくか、そもそも修正内容が混ざらないようにしたい。
競合解決をローカルで実施
ローカルでdevをマージ
$ git merge dev Auto-merging index.html CONFLICT (content): Merge conflict in index.html CONFLICT (add/add): Merge conflict in files/testa/index.html Auto-merging files/testa/index.html Auto-merging files/index.html CONFLICT (content): Merge conflict in files/index.html Automatic merge failed; fix conflicts and then commit the result.
エディタでtestbが見つかる(混入に気づける)
コマンドのほうでももちろん気づける
$ git status On branch ops/test_a You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Changes to be committed: modified: files/testa/index.html new file: files/testb/index.html Unmerged paths: (use "git add <file>..." to mark resolution) both modified: files/index.html both modified: index.html
正しく修正する
~~~~コミット~~~~
混入せずに、マージできるが、ops/test_bの修正内容は当然消える。
ので、再度ops/test_bの修正内容をコミットする必要がありそう。
これで気づかずにマージしてしまうことは防げそうなので、GitHubでコンフリクト解消するよりも、そもそもローカルで解消するほうがよさそう。
わかっていれば、GitHubでもよきかな。
(追記)混在したマージコミットをrevertする
そもそもマージコミットさえrevertできれば、よかったと気づいた
$ git revert -m [1or2] [マージコミットのハッシュ値]
1と2間違えたな~って時は以下で元に戻す
$ git reset --hard HEAD~
revertできなかった理由は、①SourceTreeを使っていたことと②マージコミットであったことが原因そう
SourceTreeでrevertをすると、コマンドを自動生成してくれるけど、通常コミット用のrevertコマンドのようでうまくいかない。
マージコミットには普通のコミットと違って親コミットが2つあるから、どっちの方をrevertするんだい!ってなってしまう。
SourceTreeをうまく使えばできるのかもしれないが、やっぱりコマンドがよさそう。