git revert <commit_hash>
単独では機能しません。-m
指定する必要があり、私はそれについてかなり混乱しています。
誰もがこれを以前に経験しましたか?
git
一致しない例ですgit-flow
。develop
チェックアウトしている場合は、当然、長年の共有開発ブランチではなく、バグが発生した2コミット機能ブランチを元に戻します。とそれを選ぶ必要があるとんでもない感じ-m 1
。
git revert <commit_hash>
単独では機能しません。-m
指定する必要があり、私はそれについてかなり混乱しています。
誰もがこれを以前に経験しましたか?
git
一致しない例ですgit-flow
。develop
チェックアウトしている場合は、当然、長年の共有開発ブランチではなく、バグが発生した2コミット機能ブランチを元に戻します。とそれを選ぶ必要があるとんでもない感じ-m 1
。
回答:
-m
オプションでは、指定した親番号を。これは、マージコミットには複数の親があり、Gitはどの親がメインラインであり、どの親がマージを解除するブランチであるかを自動的に認識しないためです。
の出力でマージコミットを表示するとgit log
、その親が次の行で始まる行にリストされていることがわかりますMerge
。
commit 8f937c683929b08379097828c8a04350b9b8e183
Merge: 8989ee0 7c6b236
Author: Ben James <ben@example.com>
Date: Wed Aug 17 22:49:41 2011 +0100
Merge branch 'gh-pages'
Conflicts:
README
このような状況では、git revert 8f937c6 -m 1
それはにあったようにあなたのツリーを取得します8989ee0
、そしてgit revert -m 2
、それはであったように木を復活します7c6b236
。
親IDをよりよく理解するには、次を実行します。
git log 8989ee0
そして
git log 7c6b236
8989ee0
、7c6b236
どこへ行く1、。どのように理解できますか?
git log 8989ee0
とgit log 7c6b236
、答えがわかるはずです。
これは誰かを助けることを期待して完全な例です:
git revert -m 1 <commit-hash>
git push -u origin master
どこに<commit-hash>
あなたが復帰したいとマージのハッシュをコミットしている、との説明で述べたように、この答えは、-m 1
あなたがマージする前に、まず親のツリーに戻すしたいことを示しています。
git revert ...
二行目は、リモートブランチにそれらを押して変更内容を公衆になりながらラインは、基本的に、変更をコミットします。
git revert
コマンドが既に作成されたコミットオブジェクトをコミット。それが起こらないようにするには、--no-commit
フラグを入力する必要があります
ベンはコミットマージを元に戻すためにどのように語っていますが、それはだ非常に重要そうすることであなたがいることを実感します
"... は、マージによってツリーの変更が発生することは決してないことを宣言します。その結果、後のマージでは、以前に元に戻されたマージの祖先ではないコミットによって導入されたツリーの変更のみが発生します。これは、そうでない場合もあります。何をしたい。」(gitのマージmanページ)。
記事/メーリングリストメッセージ manページからリンクされているが関与しているメカニズムと考慮事項について詳しく説明します。マージコミットを元に戻した場合、後でブランチを再びマージして、同じ変更が戻されることを期待できないことを理解してください。
これらの手順に従って、誤ったコミットを元に戻すか、リモートブランチをリセットして正しいHEAD /状態に戻すことができます。
git checkout development
git logからコミットハッシュ(つまり、間違ったコミットの直前のコミットのID)をコピーする
git log -n5
出力:
commit 7cd42475d6f95f5896b6f02e902efab0b70e8038 "ブランチ 'wrong-commit'を 'development'にマージします。"
commit f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 "これは間違ったコミットです"
commit 3779ab50e72908da92d7athisthiscommitthisdmitacomdthisacomddthiscdcdccf72
ブランチを前の手順でコピーしたコミットハッシュにリセットする
git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)
git status
て、間違ったコミットの一部であったすべての変更を表示します。git reset --hard
して、すべての変更を元に戻します。git push -f origin development
何も起こらないようにログをクリーンに保つには(-fをプッシュするため、このアプローチにはいくつかの欠点があります):
git checkout <branch>
git reset --hard <commit-hash-before-merge>
git push -f origin HEAD:<remote-branch>
'commit-hash-before-merge'は、マージ後のログ(gitログ)から取得されます。
push -f
共有リポジトリでは絶対に行わないでください
ロールバックする最も効果的な方法は、ステップバックして置換することです。
git log
2番目のコミットハッシュ(完全なハッシュ、リストされたミスの前に元に戻したいハッシュ)を使用し、そこから再分岐します。
git checkout -b newbranch <HASH>
次に、古いブランチを削除し、新しいブランチをその場所にコピーして、そこから再起動します。
git branch -D oldbranch
git checkout -b oldbranch newbranch
ブロードキャストされている場合は、すべてのリポジトリから古いブランチを削除し、やり直したブランチを最も中央にプッシュして、すべてに戻します。
merge
コミットを元に戻したい場合は、次のようにします。
git log
マージコミットのIDを確認します。マージに関連する複数の親IDも見つかります(下の画像を参照)。黄色で示されているマージコミットIDを書き留めます。親IDは、次の行にとして記述されているものですMerge: parent1 parent2
。さて...
ショートストーリー:
git revert <merge commit id> -m 1
のvi
コンソールを開くを実行します。書き込み、保存、終了、完了!長い話:
マージが行われたブランチに切り替えます。私の場合、それはtest
ブランチであり、feature/analytics-v3
ブランチをブランチから削除しようとしています。
git revert
コミットを元に戻すコマンドです。しかし、merge
コミットを元に戻すときに厄介なトリックがあります。-m
フラグを入力する必要があります。そうしないと失敗します。ここからは、ブランチを元に戻し、正確にそれをオンにするparent1
か、またはparent2
経由するようにするかを決定する必要があります。
git revert <merge commit id> -m 1
(に戻るparent2
)
git revert <merge commit id> -m 2
(に戻るparent1
)
これらの親をgit logして、どちらの方法にしたいかを判断できます。これがすべての混乱の原因です。
すべての回答はすでにほとんどのことをカバーしていますが、5セントを追加します。つまり、マージコミットを元に戻すのは非常に簡単です。
git revert -m 1 <commit-hash>
権限がある場合は、「master」ブランチに直接プッシュできます。それ以外の場合は、単に「revert」ブランチにプッシュしてプルリクエストを作成します。
このテーマに関するより役立つ情報は、https://itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.htmlにあります。
2つの既知のエンドポイント間にリバースパッチを作成し、そのパッチを適用するとうまくいくことがわかりました。これは、masterブランチからスナップショット(タグ)を作成したか、masterブランチのバックアップでmaster_bk_01012017を作成したことを前提としています。
マスターにマージしたコードブランチがmycodebranchだったとします。
git diff --binary master..master_bk_01012017 > ~/myrevert.patch
git apply --check myrevert.patch
git am --signoff < myrevert.patch
git branch mycodebranch_fix
git checkout mycodebranch_fix
git revert [SHA]
正しくマークされた回答は私にとってはうまくいきましたが、私は何が起こっているのかを判断するために少し時間を費やす必要がありました。
ブランチAとBを取得したとしましょう。ブランチAをブランチBにマージし、ブランチBをそれ自体にプッシュしたため、マージはその一部になりました。しかし、マージ前の最後のコミットに戻りたいと思います。あなたがやる?
git log
最近のコミットの履歴が表示されます-コミットにはcommit / author / dateプロパティがあり、マージにもマージプロパティがあるため、次のように表示されます。
commit: <commitHash>
Merge: <parentHashA> <parentHashB>
Author: <author>
Date: <date>
使用してgit log <parentHashA>
、git log <parentHashB>
-それらの親ブランチのコミット履歴が表示されます-リストの最初のコミットが最新のものです
<commitHash>
あなたのGitのルートフォルダおよび使用に行き、あなたがしたいコミットのgit checkout -b <newBranchName> <commitHash>
準備ができて、出来上がり..あなたはマージする前に選択した最後のコミットことから始まる新しいブランチを作成することを- !git revert -mに関するgit docは、これを正確に説明するリンクを提供します:https : //github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt
GitHubリポジトリのマスターブランチにマージされたPRでもこの問題に直面しました。
PRによってもたらされたすべての変更ではなく、いくつかの変更されたファイルを変更したかったので、私はwith を使用する必要がamend
ありmerge commit
ましたgit commit --am
。
手順:
git add *
またはgit add <file>
git commit --am
して検証git push -f
なぜそれが興味深いのですか?
このリンクからマージを元に戻す方法についての良い説明が見つかりました。以下の説明をコピーして貼り付けました。以下のリンクが機能しない場合に備えて、参考になります。
誤ったマージを元に戻す方法 Alan(alan@clueserver.org)はこう言っています:
私はマスターブランチを持っています。その中には、一部の開発者が取り組んでいる分岐があります。彼らはそれが準備ができていると主張します。それをmasterブランチにマージします。何かが壊れるので、マージを元に戻します。彼らはコードに変更を加えます。彼らはそれを彼らがそれが大丈夫であると言う点に達し、我々は再び合併する。調査すると、リバート前に行われたコードの変更はマスターブランチではなく、マスターブランチで行われたことがわかります。そして、この状況から回復するための助けを求めました。
「マージの復帰」直後の履歴は次のようになります。
---o---o---o---M---x---x---W
/
---A---B
ここで、AとBはあまり良くなかったサイド開発にあり、Mはこれらの時期尚早な変更をメインラインにもたらすマージであり、xはサイドブランチが行ったものと無関係でメインラインですでに行った変更であり、Wは「マージMを元に戻します(WはMを逆さまに見えませんか?)。IOW、「diff W ^ .. W」は「diff -RM ^ .. M」に似ています。
マージのこのような「元に戻す」は、次のようにして行うことができます。
$ git revert -m 1 M サイドブランチの開発者が間違いを修正すると、履歴は次のようになります。
---o---o---o---M---x---x---W---x
/
---A---B-------------------C---D
ここで、CとDはAとBで壊れていたものを修正するためのものであり、Wの後のメインラインで他の変更がすでに行われている場合があります。
更新されたサイドブランチ(その先端にDがある)をマージすると、AまたはBで行われた変更はWによって元に戻されたため、結果には反映されません。
ライナスは状況を説明します:
通常のコミットを元に戻すと、そのコミットが行ったことが元に戻され、かなり簡単です。ただし、マージコミットを元に戻すと、コミットによって変更されたデータも取り消されますが、マージによる履歴への影響はまったくありません。したがって、マージは引き続き存在し、2つのブランチを結合していると見なされます。今後のマージでは、そのマージが最後の共有状態として認識されます。また、差し込まれたマージを元に戻した復帰は、その影響をまったく受けません。したがって、「元に戻す」はデータの変更を元に戻しますが、それはほとんどありませんリポジトリの履歴に対するコミットの影響を取り消さないという意味での「取り消し」。したがって、「元に戻す」を「元に戻す」と考えると、この部分の復帰を常に見逃すことになります。はい、データは元に戻されますが、履歴は元に戻されません。このような状況では、最初に前の状態に戻す必要があります。これにより、履歴は次のようになります。
---o---o---o---M---x---x---W---x---Y
/
---A---B-------------------C---D
ここで、YはWの復帰です。このような「復帰の復帰」は、次のようにして行うことができます。
$ git revert W この履歴は(WとW..Yの変更による競合の可能性を無視して)履歴にWまたはYがまったくないことと同じです。
---o---o---o---M---x---x-------x----
/
---A---B-------------------C---D
サイドブランチを再度マージすると、以前の復帰と復帰の復帰から生じる競合は発生しません。
---o---o---o---M---x---x-------x-------*
/ /
---A---B-------------------C---D
もちろん、CとDで行われた変更は、xのいずれかによって行われたものと競合する可能性がありますが、それは通常のマージ競合です。
ライアンが述べたように、git revert
将来的にマージが困難になるgit revert
可能性があるため、あなたが望むものではないかもしれません。git reset --hard <commit-hash-prior-to-merge>
ここでは、コマンドを使用する方が便利であることがわかりました。
ハードリセットの部分を完了したら、リモートブランチ(つまりgit push -f <remote-name> <remote-branch-name>
、<remote-name>
がしばしばと呼ばれる場所)に強制的にプッシュできますorigin
。その時点から、必要に応じて再マージできます。