4

そのため、ファイルの 1 つにパッチを作成していたところ、存在しないはずのコードがいくつかありました (この悪意のあるコードによって引き起こされた Web ページのエラーと相まって)。コードは数か月前にパッチで追加され、約 1 か月前にそのコミットを元に戻すことで削除されました。だから本当にあってはならない。

どこから来たのかを突き止めるために、いくつかの方法を試しました。

  1. git Blame: 奇妙なことに、コードを追加した元のコミットのコミット タグとメッセージが表示されました。まるで元に戻すことがなかったかのように。
  2. git log -- filename: 元に戻すことを含め、そこにあると予想されるすべてのコミットを表示しましたが、その後、再表示する必要があることを示唆するものは何もありませんでした。
  3. 手動チェック パッチ (バイセクト): コードは復帰直後のコミットで再表示されましたが、そのパッチをチェックアウトすると、そのログはまったく異なり、復帰はありませんでした。

この最後の観察から、問題のパッチは失敗したマージであると結論付けましたが、コミット メッセージにはマージについての言及はなく、私たちのチームは通常、git が生成したマージ メッセージを保持しています。

それで、そのように見えますか?競合の解決中に間違った選択をして、コードが再導入されましたか? もしそうなら、この種のものを見つけるためのより速い方法はありますか? たとえば、git の非難は、コードが私の元のパッチから来たと述べています。しかし、元に戻した後、パッチ X で再導入されたことを直接教えてもらう方法はありますか? マージ中にコードが影響を受けたことがわからない場合、git はどのようにして各コードがどこから来たのかを追跡しますか? マージの競合中に誰かがそのコードをいじったことを私に伝えることができますか? 私は、マージ自体が責任を負うべきだと考えていました。

4

2 に答える 2

4

これはの決定的なケースのように見えます

Gitマージ、次に元に戻す、次に元に戻す

意味:これまでのように、マージコミットを実際に元に戻すべきではありません。代わりに、「-hard」をその前のポイントにリセットします。他の低レベルの手法も適用されますが、早送り以外のプッシュを絶対に行う余裕がない場合にのみ、それらを確認することをお勧めします(gitを以前のコミットにリセットすると、後の新しい作業をプッシュするときに「強制」プッシュが発生します)。

revertは、内容を元に戻します。ただし、元のマージコミットでは、マージソースが親コミットとして表示されます。これは、コンテンツが元に戻されたとしても(!)、リモートブランチが完全にマージされたと思い込んでしまいます。すべての可能な厄介な結果を伴います。

git show-branch mybranch previouslymergedbranch`

git log --no-walk $(git merge-base -a mybranch previouslymergedbranch)

あなたに関係を示すことで啓発するべきです


@Tesserexわかりました ...、私は「のように見える」と言いました:)

それでも、git [1]の素晴らしいが、必然的に不完全なマージ追跡(ベース検出)に噛まれている可能性があります。おそらく、マージ時にshow-branchとmerge-baseの出力を確認できます。これが最後のマージだった場合は、

git rev-list --merges --parents -1 mybranch

これにより、3つのsha1が返されます<mergecommit> <mergetarget> <mergesource>。ここで、mergecommitは単にマージが発生したときであり、mergetargetは「mybranch」であり、mergesourceは「previouslymergedbranch」であるため、上記のコマンドを実行できます。

復元力のあるコミット(元に戻したもの)がまだマージを保留していた可能性があり(gitによる)、そのため、すべてがマージされ、「元に戻す」を元に戻しました...これはさまざまな理由で発生する可能性があります(例:元のコミットが手動で転送されたか、チェリーピックが競合しているため、gitがコミットがすでにマージターゲットに適用されていることを検出できませんでした)

gitがマージ(コミットのシーケンス)の途中で競合していない(「純粋な」)チェリーピックをアクティブに検出するかどうかさえわかりません。それは確かにできますが:

git log --left-right --oneline --cherry-pick --graph --boundary mergetarget...mergesource

これにより、マージ時に2つの参照間の「コミット」のデルタとしてgitが認識するものが表示されます。git-logのマニュアルページでは、-cherry-pickがgitに、コミットID(ハッシュ)異なっていても出力からコミットを削除するように指示していますが、diffはすべての目的と目的で同じであると説明されています。


[1] OT:これは難問です。ソフトウェアをよりスマートにすることはできますが、抽象化が漏れている限り、問題が発生します。

一般的な経験則は次のように思われます。最も洗練されたツールを使用すると、問題が少なくなります。しかし、誘拐が壊れたとき、たわごとは洗練された種類のものになります:)

于 2011-04-06T21:39:53.773 に答える