web-dev-qa-db-ja.com

プルリクエスト中のマージの競合を解決するにはどうすればよいですか?

私たちは通常、マスターから離れた個々のブランチを持っています。たとえば、「JohnMaster」という名前のブランチがあります。 JohnはJohnMasterからローカルで開発を行い、コードをマスターにプッシュする準備ができたら、ブランチをリモートにプッシュしてから、JohnMasterからマスターにプルリクエストを実行します。発生した問題は、プルリクエストを実行するときに競合が発生することです。

マージの競合を解決できると思った方法は、マスターを停止し、master-> JohnMasterからローカルでリベースを実行してから、リベース中にマージの競合を解決することでした。リベースを実行した後、リモートから2コミットしたと表示されたため、コードをリモートにプッシュバックできませんでした(リベース前は同一でした)が、git pullを実行すると、別のマージ競合が発生します。

おそらくベストプラクティスは、master-> JohnMaster(逆マージ)からプルリクエストを実行し、JohnMasterでコミットをリモートにプッシュする前にgit pullを実行することですが、時々人々は忘れてしまいます。この問題が発生します。

だから私の質問は:

  1. ローカルでのリベースが機能しないのはなぜですか?
  2. この問題をどのように回避できますか?

マスターに直接コミットすることはできませんのでご注意ください。プルリクエストを必要とするブランチにはセキュリティがあります。

9
coding4fun

短い答え

Origin/masterをJohnMasterにマージし、これをリモート(Origin/JohnMaster)にプッシュします。これで、Origin/JohnMasterからmasterへのプルリクエストを実行でき、masterに新しいコミット(JohnMasterに含まれていないmasterのコミット)がない限り、マージの競合は発生しません。

git checkout JohnMaster
git merge Origin/master
#solve merge conflicts
git commit
git Push
#pull request
git Push

長い答え

git rebase Origin/masterを実行すると、実際に発生しているのは、JohnMasterに追加されたコミットが書き換えられ(この場合は2つのコミット)、マスターからのコミットの後に置かれることです。例えば。 JohnMasterブランチが作成されてから、BとCがマスターに追加され、B 'とC'がJohnMasterに追加されました。リベース後、A-> B-> C-> B ''-> C ''になります。リベースの前は、機能ブランチにA-> B '-> C'があり、プッシュする前にリモートブランチにありました。この時点で、Gitは、ローカルにB 'とC'がないことを通知します。これは、B ''とC ''に書き換えられているため、コミットが異なるためです。

この時点で、git Push -fを使用してローカルのリベースされた履歴を強制的にプッシュできます。これにより、リモートコミットB 'とC'を排除し、Origin/JohnMasterでローカルに実行するのと同じようになります。これは、A-> B-> C-> B ''-> C ''です。ここでプルリクエストを実行し、それが受け入れられた場合は、マスターブランチでこのコミット履歴を正確に取得します。

個人的には、リモートでプッシュされた履歴を書き換えるのは好きではありません。可能な限り避けるべきだと思いますが、実際にはそれはあなたが持っているオプションです。

Origin/masterをJohnMasterにマージする場合(これは私の意見では好ましい方法です)、既存のすべてのコミットをそのままにします:A-> B-> CおよびA-> B '-> C'および2つのブランチが再び結合する新しいマージコミットMを追加します。マージコミットは、2つの親(この場合はC 'とC)を持つコミットです。このマージコミットは、強制的にプッシュすることなく安全にプッシュできます。

11
Manuel Schmidt