リポジトリからファイルを消去するGitマージを元に戻す最良の方法は何ですか?


13

したがって、次のことが起こると想像してください(そして、すべてSourceTreeを使用している)。

  1. 私たちはすべてorigin / developに取り組んでいます。
  2. 私は一週間休みに行きます。
  3. 私の同僚は、過去数日間、起源/開発を自分のローカル開発ブランチにマージせずにローカルで作業しています。
  4. 彼はプッシュを試み、最初にマージする必要があると言われ、次にプルを行います。
  5. 彼は競合を取得し、マージ後の自動コミットの進行を停止します。
  6. GitがSVNに似ていると仮定すると、私の同僚は作業コピーの「新しい」ファイルを破棄してから、マージをコミットします。これらの「新しい」ファイルを発信元/開発者のヘッドから消去します。
  7. その改訂に加えて、数週間分の開発作業が行われます。
  8. 私は休日から戻ってきて、私の仕事の数日間が不足していることがわかります。

私たちはすべてGitに非常に新しい(これを使用する最初のプロジェクトです)が、それを修正するために私がしたことは:

  1. 「develop」の名前を「develop_old」に変更します。
  2. developer_oldを新しいブランチ「develop_new」にマージします。
  3. 不良マージの前の最後のコミットに、develop_newブランチをリセットします。
  4. Cherryはそれ以降、各コミットを1つずつ選択し、手作業で競合を解決します。
  5. 開発元と開発元をプッシュします。

この時点で、develop_newは、すべての変更の「良い」コピーであり、その後の数週間分の作業が再適用されることを望んでいます。私はまた、「逆コミット」がマージで奇妙なことをすることを想定しています。特に今後数週間の作業はそれに基づいているためです-そして、そのマージには私たちがたいものと一緒に欲しいものがたくさん含まれているのでt。

私はこれが二度と起こらないことを望んでいますが、もし二度と起これば、私は物事を修正するより簡単/より良い方法を知りたいです。そのマージに基づいてレポで多くの作業が行われたときに、「悪い」マージを元に戻すより良い方法はありますか?


1
gitツリーのスクリーンショット(適切に編集)またはお気に入りのgit log形式の出力を、さまざまなコミットで何が起こったのかについての適切な注釈とともに投稿できますか?(私は/注釈を墨消したいgit log --graph --pretty=oneline --abbrev-commit、そこから行く)

1
あなたには遅すぎますが、ユニットテストはそれを捕らえたでしょう。
おとなしく14年

1
@nalply:不正なマージによってユニットテストも削除された場合ではありません。
アーロンノート14年

うわー、それは本当に陰険な不運です。
おとなしく14年

回答:


6

私が正しく理解していれば、これはあなたの状況です:

    ,-c--c--c--c--M--a--a--X ← develop
o--o--y--y--y--y-´

一般的な履歴(o)の後、作業を​​コミットしてプッシュしました(y)。同僚(c)は自分のローカルリポジトリで作業し、不正なマージ(M)を行いました。その後、Mの上にいくつかの追加のコミットがあるかもしれません(a)

git reset --hard develop M^2
git branch coworker M^1

これで、グラフは不正なマージの前とまったく同じようになります。

    ,-c--c--c--c ← coworker
o--o--y--y--y--y ← develop

適切にマージする(G):

git checkout develop
git merge coworker

その結果:

    ,-c--c--c--c-、
o--o--y--y--y--y--G ← develop

次に、追加のコミットを移植します。

git reset --hard X
git rebase --onto G M develop

これにより最終結果が得られます。

    ,-c--c--c--c-、
o--o--y--y--y--y--G--a--a--X ← develop

これにより、マージの競合が増える可能性があることに注意してください。また、履歴を変更したばかりです。つまり、すべての同僚が新しい履歴にクローン/リセット/リベースする必要があります。

PS:もちろん、置き換える必要がありますのGMおよびXコミットに対応するidであなたのコマンドで。


これらのコミットのすべてが既に共有リポジトリにプッシュされているという質問ではかなり明白なようですので、リベースは良い選択だとは思いません。すべての最近のコミットを元に戻し、その後、正常なマージの上で元に戻された競合していないコミットを選択する方が安全です。
アーロンノート14年

それがclone / reset / rebaseの部分でした。-開発者が数人しかいない場合、リポジトリを更新するように伝えることは有効なオプションかもしれません。
ミカ14年

1

リポジトリを修正する方法を考えているのは良いことですが、同僚が新しいファイルを削除するだけで、大量の更新を上書きしなかった場合、削除されたファイルを単純に復元するのがはるかに簡単なアプローチです。

私はおそらく、現在行方不明になっているコードを追加した元のコミットを(現在の頭の上で)チェリーピックすることから始めます。何らかの理由で機能しない場合は、追加したファイルで古いリビジョンをチェックアウトし、新しいコミットでそれらを再度追加します。

あなたが実際に説明するのは、よく知られているGitアンチパターンのサブセットです。実際にはマージの競合を解決していませんが、まったく無関係な変更を行っています)は、マージ自体によって本質的にマスクされ、コードレビューやデバッグセッションで簡単に見落とされるため、非常に悪い習慣と見なされます

ですから、同僚にこれは壮大な失敗だと間違いなく説明してください。しかし、大手術の準備をする前に、バンドエイドをたたくことを検討してください。


私は同意します、それがあなたがすることができることの1つがファイル全体である場合、あなたができることの1つは、古いファイルの履歴を気にしない場合です:1.現在混乱しているブランチから新しいブランチを作ります。2.不良ブランチに切り替えて、レスキューブランチである別の新しいブランチを作成します。3.レスキューブランチから、コミットが失敗する前にコミットに戻ります。4.削除されたファイルをgit 5.以外の場所にコピーします。他の新しいブランチに切り替えます。6.削除されたファイルの新しいバージョンを新しいブランチにコピーしてコミットします。ライナスT.によって有名なポストである歴史を節約し、より複雑な方法があります
エリン

1
実際、これはチェックアウトを使用する方法を示していますjasonrudolph.com/blog/2009/02/25/…それははるかに優れています。
エリン14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.