web-dev-qa-db-ja.com

マージによる変更を元に戻す

開発者は2つのファイルに小さな変更をコミットしていました。しかし、このコミットの間に、彼は多くのものを削除したマージ競合がありました(おそらく最新のバージョンを持っていませんでした)。その後、共有リポジトリにプッシュされ、他の開発者が他のコミットを行いました。

マージによって重要なファイルが削除されたため、元に戻したいことがわかりました。
次のコミットから変更を失うことなくこれを行うにはどうすればよいですか?

私はgit revert commitsha、しかし、それは変更を元に戻さなかった。 mergeshaを元に戻す必要がありますか?どうすれば判断できますか?

27
Sfisioza

git revert --mainline

通常:

git revert --mainline 1 dd8cbe3e4

どこ:

  • dd8cbe3e4は、取り消したいマージコミットであり、
  • --mainlineは、以前の複数のコミットのどれが復元するかを示します(マージコミットには複数の親コミットがあり、そのうちの1つしか保持できないことに注意してください)。
    • 1が何を意味するかについての良い説明は見つかりませんが、1,2,3...は、dd8cbe3e4の直前のコミットへのマッピングのリストに対応し、ascending年代順(最も古いもの-通常は元に戻したいものです)。

ソース:

http://thezencoder.com/2013/09/05/how-to-correctly-revert-a-bad-merge-in-git/

37

要するに、[〜#〜] warning [〜#〜]:実際にはありませんsafe実際にresetコミットへの分岐beforeマージ。

今のところ、既存のリファレンスを説明し、参照します。

リンクされた回答を引用する 障害のあるgit merge commitを元に戻すには

基本的に、マージを元に戻すと、データの変更は元に戻りますが、履歴(グラフ)の変更は元に戻りません。したがって、誤ったマージを元に戻しても何も起こらないことが予想されます。

確かに、ブランチのリセットは最も簡単なアプローチですが、マージの結果が既に共有リポジトリにプッシュされている場合は、欠点があります(公開された履歴を効果的に書き換えているため)。

内訳はこちら

  • git merge <someref>マージする(競合の解決後にオプションでコミットする)
  • すぐにを見つけて、マージの前にブランチをリセットしたい場合:

    git reset HEAD@{1} 
         # optionally pass --hard to reset the working tree too
    
  • 後でしかわからない場合は、

    • reflogを使用して、マージ前のポイントを見つけます。 (HEAD@{1}は、現在のヘッドリファレンスの以前の値を短縮しますが、reflogはヘッドリファレンスの値の限られた履歴を追跡します)

      git reflog
      
    • ブランチをリセットします

      git reset HEAD@{n} # substitute reflog entry index
      
    • オプションで、マージ後に行われたコミットをリベース/チェリーピックします

      git cherry-pick HEAD@{1} # just an example. interactive tools will make this easier
      
9
sehe

別の(より安全な)アプローチは、ファイルの最後の良いバージョンと現在のバージョンの差分を作成し、コピー&ペーストで失われた部分を復元することです。

これは常に機能し、奇妙なコマンドラインオプションを必要とせず、そのままにしておくべきことを改ざんしません:-)

たとえば、Eclipseには、個々の違いを個別に選択していずれかのバージョンにコピーするための優れたツールがあります。 [比較]メニューを使用して、両方のバージョンを並べて開きます。

6
Aaron Digulla

要するに、git reset --soft <commit>(コミットはHEAD^(前)、HEAD~2(current-2)、SHAなどを実行できます。

--softを使用すると、すべての変更をコミットする準備が整うため、実際にコミットを変更できます。 --hardを使用すると、変更はすべて失われます。

コミットを変更した後、git Push --forceを使用して、共有リポジトリに変更を強制的にプッシュする必要があります。

リポジトリを共有リポジトリにリベースする必要があることを他の開発者に伝える必要があることに注意してください。 (git pull --rebaseを使用)。ただし、マージの競合が発生する可能性があります...その点に注意してください。

0
Hiery Nomus