なぜgit revertは-mオプションがないと文句を言うのですか?


185

だから私は他の人と一緒にプロジェクトに取り組んでいて、取り組んでいる複数のgithubフォークがあります。誰かが問題を修正し、彼のフォークとマージしましたが、私はもっと良い解決策を見つけることができることに気付きました。作成したコミットを元に戻したいのですが。私はこれをやってみましたgit revert HEADが、それは私にこのエラーを与えました:

致命的:コミット<SHA1>はマージですが、-mオプションが指定されていません。

どういう意味ですか?マージしてコミットしたとき、-mオプションを使用して「Merged with <username>」と言いました。

ここで何が悪いのですか?

回答:


217

デフォルトではgit revert、マージコミットを元に戻すことを拒否します。これは、実際の意味が曖昧であるためです。私はあなたHEADが実際にマージコミットだと思います。

マージコミットを元に戻す場合は、マージのどの親をメイントランクと見なすか、つまり元に戻す対象を指定する必要があります。

多くの場合、これは親ナンバー1になります。たとえば、オンになっmasterていてgit merge unwanted、のマージを元に戻すことにした場合などunwantedです。最初の親はマージ前のmasterブランチで、2番目の親はの先端になりunwantedます。

この場合、次のことができます。

git revert -m 1 HEAD

4
わかりました。マージの影響を受けた2つのファイルを変更してから、他の変更もコミットする方が簡単だと思いました。
icnhzabot

43
-m1または-m2を使用する必要があるかどうかの情報はどこにありますか?...
Patrick Cornelissen

34
git cat-file -p [MERGE_COMMIT_ID]親ブランチを順番に表示します。リストされている最初のもの-m 1は、2番目になり-m 2ます。
nostromo 2016年

2
git revert [HASH] -m 2ブランチ1.x-1.xでコミットするものは何もない、作業ディレクトリはクリーンですが私のコミットは元に戻されません
ジェンランプトン2016年

3
したがって、過去の10回のマージを元に戻す必要がある場合(gitが別の開発者から変更をプルするたびに自動的にマージを実行するため、これはかなり可能性があります)、マージごとにこれを実行する必要がありますか?元に戻すことは基本的に役に立たないので、これがgitファンがリベースに熱心である理由ですか?
ニュートリノ2017

46

他の男がfooの上にバーを作成したが、その間にバズを作成してからマージすると、

$ git lola
* 2582152(HEAD、マスター)分岐 'otherguy'をマージ
| \  
| * c7256de(otherguy)バー
* | b7e7176 baz
| /  
* 9968f79 foo

注:git lolaは非標準ですが便利なエイリアスです。

サイコロなしgit revert

$ git revert HEAD
fatal:Commit 2582152 ...はマージですが、-mオプションが指定されていません。

チャールズ・ベイリーはいつものように素晴らしい答えを出しまし。のように使用git revertする

$ git revert --no-edit -m 1 HEAD
[master e900aad]「Merge branch 'otherguy'」を元に戻します
 変更されたファイル0、挿入0(+)、削除0(-)
 削除モード100644バー

bar履歴を効果的に削除して生成します

$ git lola
* e900aad(HEAD、マスター)「Merge branch 'otherguy'」を元に戻す
* 2582152分岐 'otherguy'をマージ
| \  
| * c7256de(otherguy)バー
* | b7e7176 baz
| /  
* 9968f79 foo

しかし、私は、あなたがしたい疑う捨てるコミットマージを:

$ git reset --hard HEAD ^
HEADは現在b7e7176 bazにあります

$ git lola
* b7e7176(HEAD、マスター)baz
| * c7256de(otherguy)バー
| /  
* 9968f79 foo

マニュアルに記載されているとおりgit rev-parse

<rev>^、たとえばHEAD ^、v1.5.1^0リビジョンパラメータの
サフィックス^は、そのコミットオブジェクトの最初の親を意味します。n番目の親を^<n>意味します(つまりと同等)。特別なルールとして、はコミット自体を意味し、がコミットオブジェクトを参照するタグオブジェクトのオブジェクト名である場合に使用されます。 <rev>^<rev>^1<rev>^0<rev>

したがって、を呼び出す前git resetHEAD^(またはHEAD^1)はb7e7176で、HEAD^2c7256deでした。つまり、マージコミットの最初の親と2番目の親です。

git reset --hard作業を破壊する可能性があるので注意してください。


3
それは混ざり合い、混乱し、世界を揺さぶったものです。Lolaを除きます。この素晴らしいエイリアスをありがとうございました。
Barney

lolagitコマンドに追加する簡単な方法:git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all"
D.ギブス

8

私はこの問題を抱えていましたが、解決策は(gitkを使用して)コミットグラフを見て、次のことを確認することでした:

*   commit I want to cherry-pick (x)
|\  
| * branch I want to cherry-pick to (y)
* | 
|/  
* common parent (x)

やりたいことを理解しました

git cherry-pick -m 2 mycommitsha

これは-m 1、共通の親に基づいてマージするので-m 2、ブランチyに基づいてマージするので、それをチェリーピックしたいためです。


1
おそらくgit-revertこれはとは関係がないためです。
pnomolos 2016年

1
この質問は-mオプションに関するものであり、に関するものではないと思いますgit merge。つまり、この-mオプションを使用する理由は、リバートとチェリーピックの場合と同様です。それが事実でない場合は、お知らせください。チェリーピックの使い方を具体的に説明する他の質問を見つけられなかったので、この回答に感謝します。おそらく、この質問を見つけて有用で適切なディスカッションを見つけるのに役立ちました。
nealmcb 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.