**「upstreamのmasterブランチをマージしようとしたら大量のコンフリクトが発生した」**こと、ありませんか?
私はよくあります
**「せっせっとコンフリクトを解消してるけど、そろそろ時間切れ。このブランチ、いったんプッシュしたいなぁ」**ということ、ありませんか?
私はよくあります
ですが、未処理のコンフリクトを残したままコミットしようとしても、
$ git commit
error: 'commit' is not possible because you have unmerged files.
hint: Fix them up in the work tree,
hint: and then use 'git add/rm <file>' as
hint: appropriate to mark resolution and make a commit,
hint: or use 'git commit -a'.
fatal: Exiting because of an unresolved conflict.
(意訳:コンフリクトの解決終わってないからコミットなんてできません~)
とGitに怒られてしまうわけです。そこをなんとか……ということで、とりあえず作業状態を一時保存(コミット)してプッシュしておいて、あとからなんとかする方法を模索してみます。
ツッコミ大歓迎です
一時保存の方法
コンフリクト解消作業中に以下のコマンドを実行すれば、「とりあえず作業状態を一時保存(マージコミット)してプッシュ」できます。
$ git add .
$ git commit
$ git push <リモート名> <マージ作業中のブランチ名>
一時保存した内容を別端末にプルしたら、コンフリクト解消作業を再開しましょう。
- コンフリクト未解消ファイルの状態に応じて、下記の手順でコンフリクト状態を復元する
- 復元されたファイルを使って、コンフリクトを解消する
- コンフリクトが解消できたら、
git add <fileapth> ; git commit --amend
で、該当ファイルをマージコミットに追加する
コンフリクト解消前のファイルを一時保存した場合
まずはコンフリクトを一切解消していない状態のファイルから。このコマンドを実行すると、一度コミットしたファイルを、マージ直後のコンフリクト解消前状態に戻せます。
$ git checkout --conflict=merge <filepath>
Gitもこのファイルを「コンフリクト未解消」とみなしてくれますので、マージツールなどとの連携もいつもどおり可能です。
コンフリクト解消中のファイルを一時保存した場合
上のコマンドだけだと「マージ直後のコンフリクト解消前」の状態に戻ってしまうので、「コンフリクトを途中まで解消した一時保存の状態」はなくなってしまいます。それはつらい……ということで、git show
コマンドの出番です。
$ git checkout --conflict=merge <filepath>
$ git show HEAD:<filepath> > <filepath>
こうすれば、一時保存状態を再現しつつ、Gitがこのファイルを「コンフリクト未解消」とみなしてくれるようになります。
注意
- マージ作業用のブランチを前もって作成しておく
- あとで
git push -f
しても問題ないリモートを使う
ようにしましょう。一時保存なコミットをmasterブランチに直接追加するのはのは避けるべきですし、「git push -f
だめ、絶対っ!」というルールがあるリポジトリ(リモート)もたくさんあるからです。