Gitで元に戻されたマージを再実行する


231

ここで少し問題に遭遇しました:28sGitに問題固有のブランチがあり、それを一般developブランチにマージしました。実行が速すぎることが判明したため、git-revertを使用してマージを元に戻しました。しかし、今はにマージ28sする時が来ましたがdevelop、git-mergeコマンドは元のマージを確認し、すべてが正常でブランチがすでにマージされていることを喜んでお知らせします。私は今何をしますか?'Revert "Revert" 28s-> develop ""」コミットを作成しますか?良い方法ではないようですが、今のところ他には想像できません。

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

Gitログ出力


4
それはGitX(gitx.frim.nl)です。
トムズミコス2009

回答:


169

「元に戻す」を行う必要があります。元の状態に戻す方法によっては、思ったほど簡単ではない場合があります。このトピックに関する公式ドキュメントをご覧ください。

---o---o---o---M---x---x---W---x---Y
              /
      ---A---B-------------------C---D

許可する:

---o---o---o---M---x---x-------x-------*
              /                       /
      ---A---B-------------------C---D

しかし、すべてうまくいくのでしょうか?もちろんです。マージを元に戻すことができ、純粋に技術的な観点から、gitは非常に自然にそれを実行し、実際の問題はありませんでした。
それは、「マージ前の状態」から「マージ後の状態」への変化と考えただけでした。
複雑でも、奇妙でも、本当に危険でもありません。Gitはそれについて何も考えずにそれを行います。

したがって、技術的な観点からは、マージを元に戻すことに何の問題もありませんが、ワークフローの観点からは、一般的に回避する必要があります。

あなたは、メインツリーにマージされてしまった問題見つけた場合、すべては、例えば、可能であればむしろマージ元に戻すよりを、してみてください本当にハードに

  • マージしたブランチに問題を二分し、修正するだけです。
  • または、それを引き起こした個々のコミットを元に戻そうとします。

はい、それはより複雑で、いいえ、常に機能するとは限りません(時には、「おっと、まだ統合する必要はありませんでした。まだ準備ができていないため、本当にすべてを元に戻す必要があります」マージ")。したがって、実際にはマージを元に戻す必要がありますが、マージをやり直す場合は、元に戻すことで元に戻す必要があります。


10
良いリンク(+1)。私は、読者がこの場合に関連するオプションをすぐに見ることができるように、回答のドキュメントの一部を自由にコピーすることにしました。同意しない場合は、遠慮なく元に戻してください。
VonC 2009

5
これを実行する必要がある場合に遭遇しただけで、楽しみがここで止まるわけではありません。マージされたのは実行時間の長いブランチだったので、引き続き更新する必要がありました。ここでの私のアプローチ:tech.patientslikeme.com/2010/09/29/...
jdwyah

私は@jdwyahのブログ投稿をフォローしましたが、それは見事でした(真剣に、それがうまくいったのは素晴らしいことでした)。
hellatan 2013

2
@jdwyahはリンク切れのようですが、興味深い読みのようです。これはarchive.orgミラーですが、画像がありません:web.archive.org/web/20111229193713/http
//…

15
ブログの投稿が復活しました。ありがとう:blog.jdwyah.com/2015/07/dealing-with-git-merge-revisions.html
jdwyah

53

そのような歴史があるとしましょう

---o---o---o---M---W---x-------x-------*
              /                      
      ---A---B

ここで、A、Bはコミットに失敗し、WはMの復帰です。

そこで、見つかった問題を修正する前に、ブランチにWコミットをチェリーピックします

git cherry-pick -x W

次に、ブランチでWコミットを元に戻します

git revert W 

修正を続けられるようになった後。

最終的な履歴は次のようになります。

---o---o---o---M---W---x-------x-------*
              /                       /     
      ---A---B---W---W`----------C---D

PRを送信すると、PRが元に戻され、新しいコミットがいくつか追加されたことが明確に示されます。


3
これは役立つ可能性があるように見えますが、詳細(最後の図のC、Dは何であるか)がまばらであるため、役立つよりもイライラします
アイソクロナス

4
@Isochronous C及びDは、AとBによって導入された問題を修正コミットように見える
トーマス

@Thomas正確
Maksim Kotlyar 2017

マスターにマージする前に最終的な「健全性チェック」を提供できるので、このインスタンスでPRを使用して強調表示したのは良いことです。
Willem van Ketwich、

なぜ元のWからブランチを再開するのですか?つまり、トピックをWから続け、W`の後にCとDを続けますか?これにより、一部の重複が削除されます
Erik Carstensen

12

ワークフローを無駄にすることなく元に戻すには:

  • ローカルの開発のゴミ箱コピーを作成する
  • 開発のローカルコピーのコミットを元に戻す
  • そのコピーを機能ブランチにマージし、機能ブランチをgitサーバーにプッシュします。

準備ができたら、機能ブランチを通常どおりマージできるようになりました。ここでの唯一の欠点は、履歴にマージ/リバートコミットがいくつか追加されることです。


混乱を防ぐために、機能ブランチの「ゴミ箱」コピーを作成し、元に戻した開発をマージしました。
jhhwilliams

ありがとうございました!これは、これを行うべきではないと言うのではなく、実際にそれを行う方法を説明する唯一の答えです。本当に役に立ちました。
エミー

ありがとう、これは本当に役に立ちました。:)
DanielStracaboško

11

GITで元に戻すには:

git revert <commit-hash-of-previous-revert>

1
これを私の作業ブランチで使用して元に戻し、次に新しいPRを開発します。これで、gitは以前のPRにあったすべての変更を元に戻しました。ありがとう。
ダンスタン

3

代わりに使用してのgit-revertあなたの中に、このコマンドを使用することもできましたdevelし、分岐捨てる間違ったマージは(だけでなく、それを元に戻すの)コミット(アンドゥ)。

git checkout devel
git reset --hard COMMIT_BEFORE_WRONG_MERGE

これにより、作業ディレクトリの内容もそれに応じて調整されます。注意してください

  • (間違ったマージのため)開発ブランチに変更保存します。変更もによって消去されるためgit-resetです。git reset引数として指定したコミット以降のコミットはすべてなくなります!
  • また、リセットが履歴を書き換えるため、変更がすでに他のリポジトリからプルされている場合は、これを行わないでください。

git-resetこれを試す前に、manページを注意深く検討することをお勧めします。

ここで、リセット後に変更を再適用してdevelから、

git checkout devel
git merge 28s

これは、から28sへの本当のマージになりますdevel(gitの履歴から削除されます)。


8
組み合わせには注意してください:gitのとスーパー慣れていないと、これらの指示に従っしたい場合があります誰のためreset --hardとをpush origin。また、強制的に配信元にプッシュすると、GitHub上の公開されているPRが実際に失敗する可能性があることに注意してください。
funroll 14

プライベートgitサーバーでのマージの問題を修正するのに非常に役立ちます。ありがとう!
mix3d 2015年

1
このテクニックの+1。破壊的な可能性がありますが、慎重に適用すると、頭痛の種を大幅に減らすことができます(また、歴史を壊すこともできます)。
シリコンロックスター2017年

1

同じ問題に直面したときに、この投稿を見つけました。ハードウェアのリセットなどを行うには、上記のwayyyから怖い方法を見つけます。不要なものを削除してしまい、元に戻すことができなくなります。

代わりに、ブランチを例に戻したいコミットをチェックアウトしましたgit checkout 123466t7632723。その後、ブランチに変換されgit checkout my-new-branchます。次に、不要になったブランチを削除しました。もちろん、これは、失敗したブランチを破棄できる場合にのみ機能します。


1
git reflog後であなたが失われたコミットが必要であることを発見した場合には数ヶ月のカップルのためのハードリセットであなたを守ります。reflogはローカルリポジトリに限定されています。
Todd

1

元に戻すには、以下の手順に従うことをお勧めします(SHA1など)。

git checkout develop #go to develop branch
git pull             #get the latest from remote/develop branch
git branch users/yourname/revertOfSHA1 #having HEAD referring to develop
git checkout users/yourname/revertOfSHA1 #checkout the newly created branch
git log --oneline --graph --decorate #find the SHA of the revert in the history, say SHA1
git revert SHA1
git push --set-upstream origin users/yourname/revertOfSHA1 #push the changes to remote

ブランチのPRを作成します users/yourname/revertOfSHA1


1
  1. 元のマージの前にコミット時に新しいブランチを作成します-それを 'develop-base'と呼びます
  2. 「develop-base」の上に「develop」のインタラクティブなリベースを実行します(すでに上にある場合でも)。インタラクティブなリベース中に、マージコミットとマージを元に戻したコミットの両方を削除する機会があります。つまり、両方のイベントをgit履歴から削除します

この時点で、定期的に行うように機能ブロックをマージできるクリーンな「開発」ブランチがあります。


このアプローチは、開発ブランチが他のユーザーと共有されている場合に問題を引き起こします。
PSR
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.