2

これらのコミットを含むマスター ブランチと代替ブランチがあります。

A --- B --- C --- D (master)
       \
        E --- F --- G (sprint1)

マージが完了し、いくつかのコミットが失われ、人々がブランチでコミットし続けたときに、何か問題が発生しました:

A --- B --- E --- F --- G --- (M) (master)

A --- B --- E --- F --- G --- (M) --- H --- I (master)

それを行うためのより良い方法は何ですか?

A --- B --- C --- D --- E --- F --- G --- H --- I

私は git rebase をしようと考えていますが、このように解決しなければならない衝突がたくさんあります。

4

1 に答える 1

0

問題の再確認

したがって、レポの現在の状態は次のとおりです。

A --- B --- C --- D ------
       \                  \
        E --- F --- G --- (M) --- H --- I --...-- Z (master)

Cしかし、マージは成功しなかったため、 &で表される変更は現在のブランチDに適切に組み込まれていません。master

できない(痛みを伴わずに)

残念ながら、次の状態に到達することはできません。

A --- B --- C --- D --- E' --...-- Z' (master)

master 現在のブランチを自分のリポジトリにプルしたすべての人に問題を引き起こすことはありません。

すべてが失われるわけではありません

ただし、同様の結果を得る方法はいくつかあります (ただし、マージの競合が発生しないとは約束できません)。あなたのコメントから、欠落しているコミットの参照を知っていると思います。便宜上、次のコミットにタグを付けていると仮定します。

$ git tag <ref-to-D> oldmaster
$ git tag <ref-to-G> premerge
$ git tag <ref-to-H> postmerge

年表を失う

コミットの年表を維持することをあまり気にしない場合 (つまり A --- B --- C --- D --- E --...)、最も簡単な方法は、おそらく現在の にリベースすることmasterです:

$ git checkout oldmaster

$ git rebase master
  # deal with any merge-conflicts

$ git push origin master
  # get it out there before anyone else extends the branch further!

すべてが計画どおりに進むと、ブランチは次のようになります。

A --- B --- E --- F --...-- Z --- C' --- D' (master)

紛争の痛みを誇張していますか?

本当に年表を維持したい場合は、古いものにリベースしてみましょう master:

(どのように失敗したかによって、元のマージがこのアプローチで問題を引き起こす可能性があります。その場合は、3 番目のアプローチで対処します)

$ git checkout master

$ git rebase oldmaster
  # deal with any merge-conflicts

これはあなたが恐れていた対立の時です... しかし、それはそれほど苦痛ではないかもしれません. 通常、Git はブランチ間の違いへの対処に非常に優れているため、ここで必要な手動操作はそれほど多くない場合があります。

それが完了すると、ブランチは次のようになります。

A --- B --- C --- D -------- E' --- F' --...-- Z' (master)
       \                  \
        E --- F --- G --- (M) --- H --...-- Z (origin/master)

私たちが今直面している大きな問題は、他の誰もが支部Zの責任者 だと思っていることです。多くの痛みや苦しみを引き起こすことなく、masterあなたの新しいものを他の人に押し付けることはできません. masterおそらく今行うべき最もきちんとしたことは次のとおりです。

$ git merge -s ours origin/master
  # this creates a merge commit between the two master branches, but the file
  # contents will be identical to our new master branch

$ git push origin master

画像は次のようになります。

A --- B --- C --- D -------- E' --- F' --...-- Z' --- (M2) (master)
       \                  \                           /     (origin/master)
        E --- F --- G --- (M) --- H --...-- Z --------

一歩一歩進んでください

以前の結果は気に入ったかもしれませんが、競合が多すぎました。あるいは、以前の失敗したマージが醜い頭を上げて問題を引き起こしたのかもしれません。

最後のアプローチとして、小さなステップで試してみましょう。まず最初に、元のマージ時にあったはずのブランチを作成しましょう:

$ git checkout oldmaster

$ git rebase premerge
  # remember I "assumed" you had tagged those refs?
  # deal with any merge-conflicts

この状態を確認する必要があります。

A --- B --- C --- D -------- E' --- F' --- G' (oldmaster)
       \                  \
        E --- F --- G --- (M) --- H --- I --...-- Z (master)

そのマージ コミットをスキップして、コミットを取り込もうとしHます –<code>Z. あなたがここにいるので、私は少し用心深く感じているので、H最初に自分で持ち込みます:

$ git cherry-pick postmerge
  # deal with any merge-conflicts

困難な紛争が発生する場合、それらはおそらくここにあります。まだそれらを解決する必要がありますが、少なくともそれらは 1 つのコミットを表しているだけです (彼は、自分でそれらをマージする必要がないことを知っていると言っています!)。

ツリーは次のようになります。

A --- B --- C --- D -------- E' --- F' --- G' --- H' (oldmaster)
       \                  \
        E --- F --- G --- (M) --- H --- I --...-- Z (master)

最後のプッシュの準備はできましたか? master から残りのコミットを取り込み、以前と同様にマージ コミットを作成して、他のユーザーを新しいブランチに安全に取り込むことができるようにします。

$ git cherry-pick postmerge..master

$ git merge -s ours master

これにより、次のようになります。

A --- B --- C --- D -------- E' --- F' --...-- Z' --- (M2) (oldmaster)
       \                  \                           /
        E --- F --- G --- (M) --- H --...-- Z --------
                                           (master)

ブランチで作業していたので、プッシュバックする前oldmasterに実際のブランチを早送りする必要があります。master

$ git checkout master
$ git merge oldmaster
  # fast-forward merge

$ git push origin master

そして、それはそれであるべきです!

于 2013-06-17T20:27:52.910 に答える