1

ユーザーが「誤って」gitマージの競合を修正し、物事を壊すという問題がよく発生します。

競合があった最近のマージを見つけるために使用できるパラメーターがありませんかgit log、どの git ユーザーがその競合を解決しましたか?

場合によっては、これは誰かが master を「test」ブランチにマージするときであり、多くの人々の作業が含まれている可能性があります。

ワークフロー:-

  • マスターに基づいて機能ブランチでいくつかの作業を行います。
  • テストのために機能ブランチを「テスト」ブランチにマージします。
  • マスターは、最新の状態に保つためにテスト ブランチにマージされることがあります。

git ワークフローは大幅に改善し、より厳密にする必要がありますが、マージの競合を誤って修正しているユーザーを見つけるために短期的にできることはありますか?

4

1 に答える 1

2

ある意味、本当に些細なことです。別の意味で、それは非常に難しいです。

これが簡単な方法です:

  • 合流があります。マージは正しく行われたか、間違って行われたかのどちらかです。マージを見て、それが正しかったか間違っていたかを確認してください。間違っていれば、作者とコミッターは誰がそれをしたかを教えてくれます (あなたが作者とコミッターを信頼している限り)

これが非常に難しい方法です:

  • 合流があります。そうですか?

その質問に対する答えを自動的に見つける方法はありません。

優れた自動テストがあれば、質問への自動回答に任意に近づけることができます。優れた自動テストは簡単ではなく、非常に優れたものにしようとすると非常に難しくなります。

自動化されたテストがなくても、正しくマージを行うのが得意な人がいる場合は、スポット チェックを行うことができます。これらの優れた人々にマージを繰り返してもらい、その結果を以前の結果と比較してもらうだけです。同じであれば、元のマージは正しく行われています。それが違うなら、そうではありませんでした。

マージ競合の有無は、マージが正しく行われたかどうかの確実な指標ではありません。Git には秘密の知識はありません。固定された一連の規則に従ってテキストを結合するだけです。とはいえ、手動テストのために、特に競合が発生したマージを選択したい場合は、この部分を自動化できますマージを繰り返して (git rerereオンになっていないことを確認してください)、競合がないかどうかを確認してください。

合流を繰り返す

上記では、「repeat the merge」というフレーズが 2 回表示されています。マージをどのように繰り返すことができるか疑問に思うかもしれません。これはほとんど些細なことです。2 まず、各マージのコミット ID を見つけます。

git rev-list --merges <start-point> [additional options if desired]

これにより、候補 ID のリストが生成されます。(それらをすべてどこかに保存し、チェックしたものに注釈を付けて、後で再チェックする必要がないようにする必要があります。ここでは、好きなアドホックソリューションを使用してください。)

次に、マージ ID を指定して、最初の親を切り離された HEAD としてチェックアウトしgit merge、残りの親 ID で実行します (このビットは POSIX シェルの動作と構文に依存します)。

id=c79a113...          # or whatever, from your list
set -- $(git rev-parse ${id}^@)
git checkout $1        # check out first parent
shift                  # now that we have $1 out, discard $1
git merge $*           # (attempt to) merge the remaining commits

rev^@表記はgitrevisionsからのもので、「指定されたリビジョンのすべての親」を意味します。すべてのマージが標準の 2 つの親マージである場合は、より明確な (しかし一般的ではない) 方法を使用できます。

git checkout ${id}^1
git merge ${id}^2

gitrevisions構文とシェルsetshiftテクニックにより、タコのマージが可能になります)。

このマージはデタッチされた HEAD で行われているため、結果のマージが自動的に完了する場合、他のコミットまたはブランチ名をチェックアウトすることで簡単に破棄できます。が競合して失敗した場合はgit merge、マージが競合しており、通常の結果がインデックスに表示されます。続けてマージを終了するか、 を使用git merge --abortして終了できます。(マージが成功した場合の終了ステータスはgit mergeになり、そうでない場合はゼロ以外になります。)0


1プッシュまたはフェッチによるコミット転送を除いて、すべての Git 操作は、自分のリポジトリを完全に制御できる人物によってローカルで行われることに注意してください。もちろん、ユーザーは嘘をつき、他人であると主張することができます。これを制御する場合は、転送境界で行うことができますし、そうしなければなりません: 他の誰かからコミットを取得すると、git fetch自分の側からか、相手の側からかを問わず、誰と話しているgit pushかがわかります。(どのような認証を導入しても、これは完全に Git の外部にあり、通常は最近では ssh または https からのものであり、多くの場合、Gitolite などのサードパーティの拡張機能にラップされているか、GitHub などによってサービスとして提供されています)。この時点で、コミットを受け入れる前に、好きな検証を行う機会があります。

または、PGP 署名などを使用して「事後」に確認することもできます。誰かがいくつかのタグやコミットに PGP 署名をしており、これらの署名を検証できる場合、それらのタグやコミットが彼らのものであると信じることができます。次に、その信頼を (もちろん、SHA-1 のセキュリティと署名者をどれだけ信頼しているかに基づいて、あなたが望む範囲で) それらのコミットやタグの先祖に拡張することができます。定義済みの SHA-1 とそのテキストは、少なくとも非常に難しいものです。(これは2 番目のプレイメージ抵抗と呼ばれます。たとえば、この crypto.stackexchange.com の質問を参照してください。)

2ユーザーが提供したオプションはgit mergeここでは利用できないため、「ほとんど些細なこと」と言います。非標準のマージ オプションを使用するユーザーに、それらをコミットまたはコミットに添付されたメモに記録するように要求できますが、これを実施するのは困難です。脚注 1 も参照してください: 適用ルールは転送境界でのみ適用できます。

于 2016-11-15T16:01:55.880 に答える