LoginSignup
26
30

More than 5 years have passed since last update.

コンフリクト解消中のGitブランチを、作業途中でプッシュしたい

Posted at

「upstreamのmasterブランチをマージしようとしたら大量のコンフリクトが発生した」こと、ありませんか?

私はよくあります :cold_sweat:

「せっせっとコンフリクトを解消してるけど、そろそろ時間切れ。このブランチ、いったんプッシュしたいなぁ」ということ、ありませんか?

私はよくあります :coffee:

ですが、未処理のコンフリクトを残したままコミットしようとしても、

$ 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に怒られてしまうわけです。そこをなんとか……ということで、とりあえず作業状態を一時保存(コミット)してプッシュしておいて、あとからなんとかする方法を模索してみます。

ツッコミ大歓迎です :bow:

一時保存の方法

コンフリクト解消作業中に以下のコマンドを実行すれば、「とりあえず作業状態を一時保存(マージコミット)してプッシュ」できます。

$ git add .
$ git commit
$ git push <リモート名> <マージ作業中のブランチ名>

一時保存した内容を別端末にプルしたら、コンフリクト解消作業を再開しましょう。

  1. コンフリクト未解消ファイルの状態に応じて、下記の手順でコンフリクト状態を復元する
  2. 復元されたファイルを使って、コンフリクトを解消する
  3. コンフリクトが解消できたら、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がこのファイルを「コンフリクト未解消」とみなしてくれるようになります。

注意

  1. マージ作業用のブランチを前もって作成しておく
  2. あとでgit push -fしても問題ないリモートを使う

ようにしましょう。一時保存なコミットをmasterブランチに直接追加するのはのは避けるべきですし、「git push -fだめ、絶対っ!」というルールがあるリポジトリ(リモート)もたくさんあるからです。

26
30
1

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
26
30