5

私はマスターと開発ブランチを維持する git リポジトリで働いています。変更は開発中に行われ、リリース前にマスターにマージされます。今日、誤ってマスターを開発にマージし、結果を開発にプッシュしました。git log開発中の Aにmerge develop into masterコミットが表示されるようになりました。これをどうにか修正する必要があります。を使用して、最新の適切なコミットを見つけましたgit reflog。それに戻るための正しいアプローチは何ですか?

すでにプッシュ済みなので、履歴の書き換えは避けたいです。ただし、使用できるかどうかはわかりませんgit revert。私が元に戻したいコミットはマージ自体であるため、「不完全なマージを元に戻す」方法とその他の SO の質問が適用されるとは確信していません ( https://www.kernel.org/pub/software/scm/git/docs /howto/revert-a-faulty-merge.txt )。

4

4 に答える 4

10

マージを元に戻すために使用できます。git revertこれを行うと、将来の「再マージ」がより困難になることに注意してください。あなたが密接にリンクしたそのメッセージを読んでください - それは将来の「再マージ」を機能させる方法について多くを述べています - しかし、それはdevelopへのマージについて話していることに注意してmasterください.masterdevelop

A -- B -- C -- D -- E          <-- master
      \          \
       F - G - H - M           <-- develop

この場合 (逆ではなく にマージmasterした場合develop)、多くの異なるオプションを選択できますが、すべてに長所と短所があります...

オプションである場合、私が好む最も簡単な方法

(0) 何もしない。マージしてもブランチが壊れない場合CDdevelopそのままにしておいてください。後で、誰かがこれgit checkout masterを取得します(最初にもう1つのコミットが追加されたとしgit merge --no-ff developましょう):Idevelop

A -- B -- C -- D -- E -- M2    <-- master
      \          \      /
       F - G - H - M - I       <-- develop

であったから分離されて以来、 でmerge行われたことを次に示します。したがって、 、、およびを入れて、外れた部分 (おそらくすべて) をスキップし、最後に入れてマージコミットを行います( commit のため; しかし、そこになかった場合は、私も使用したためです) .developmasterBFGHMmasterIM2EE--no-ff

明らかな欠点があるいくつかの簡単な方法

(1)「履歴を書き換える」だけです:Mブランチからコミットを消去しdevelopます。ブランチを使用する他のすべての人に、これが起ころうとしていることを警告してMください: そのコミットはなくなり、これに対処するために必要なあらゆる手段を講じる必要があります。

(2) 古い名前の使用をやめdevelop、新しいブランチ名develop1などを作成します。

A -- B -- C -- D -- E          <-- master
     |           \
     |             M           <-- develop
      \          /
       F - G - H               <-- develop1

これはオプション (1) と同じですが、コミットMはブランチ ラベルと共にまだそこにあり、 commit を指す新しい/異なるブランチ ラベルがありますH。全員に警告する必要はありますが、作業が容易になる可能性があります。develop後で削除することもできます。

元に戻すとその欠点

(3) マージを元に戻します。Wリンクされた記事のように、新しい復帰コミットを表すために使用しましょう。

A -- B -- C -- D -- E          <-- master
      \          \
       F - G - H - M - W       <-- develop

何が入っていWますか?マージの「効果を消去」するために必要なものは何でも。Cこの場合、これは、およびで行われたことを元に戻す変更を意味しDます。これまでのところ、 、、およびdevelopからの変更点が再びあります。問題は後で発生します。FGH

git checkout master
git merge develop

master2 番目のコマンドは、とが分割された場所を探すためにルート検索を行いますdevelop(つまり、 commit B)。これにより、それ以降のすべての変更が取得されます。この時点で に含まれているものはW、元に戻すCDであり、望んでいたものとはまったく異なります。C後で修正できますが、マージを行う人は誰でも、この「削除とD」時限爆弾が待っていることを知っておく必要があります。

これは、「何もしない」オプション (0) と同じマージであることに注意してください。ここでの問題は の内容ですW。(0) の場合は commit の内容が必要ですIが、ここでは の内容は必要ありませんW

もう1つのオプション

上記の内容を考えると、これは間違いなく最悪のオプションですが、とにかくリストします。

(4)保持したいコミットのコピーを含むまったく新しいブランチを作成し、名前を付けますdevelop。(または、別の名前を付けますが、develop1上記のような状況に戻るので、おそらくそのような状況を使用する必要があります。)old-developブランチを保持するか、(ラベルを付けずに) 放棄するかは、次第です。あなたですが、私はそれを描きます:

       F' - G' - H'            <-- develop
      /
A -- B -- C -- D -- E          <-- master
      \          \
       F - G - H - M           <-- old-develop

これは、あなたが含めたリンクで説明されています。より複雑な場合にのみ本当に役立ちます。

于 2013-10-01T02:35:17.433 に答える
2

これを修正するには、ローカル ブランチを最後の適切なコミットにリセットし、それをプッシュします。

git checkout develop
git reset --hard lastgoodcommit
git push origin develop

アップストリーム リポジトリでは、デフォルトで非早送りマージが許可されていない場合があることに注意してください。その場合、アップストリームでそのオプションを変更し、上記のプッシュを実行してから、元の設定を復元する必要があります。

于 2013-10-01T01:37:19.560 に答える
0

私はGIT拡張機能を使用しています。UI でリビジョンを右クリックして元に戻す機能があります。

于 2013-10-01T01:34:41.867 に答える