9

わかりました、これがケースです:

数年前、コードベースの複数のファイルに複数の変更が加えられ、一度にコミットされました。これらの変更のどこかにバグが隠されています。git bisect を使用して、原因となったコミットをすぐに突き止めることができましたが、そのコミットの変更の量が多すぎて、少し気が進まなくなりました。

悪いコミットを見つけるのは git bisect を使えば簡単ですが、見つかったら、それをすべてブームにした単一の変更を追跡する最良の方法は何ですか? 影響を受けるファイルを 1 つずつ以前のバージョンに戻しますか?

4

3 に答える 3

4

その大規模なコミット内で発生したすべての変更を十分に理解していない限り、これはかなり退屈な作業になる可能性があります。

通常、非常に大きな (悪い大きな) コミットには、さまざまな変更が含まれます。あなたがする必要があるのは、これらすべての変更を概念的に分離し、異なるコミットを書き直すことです。

次の 4 つの基準に従って変更を分類することをお勧めします。

[NEW] 単独で特定された技術レベルの機能に関連するすべてのコードを含みます (複数の技術レベルの機能を含む可能性のあるユーザー レベルとは対照的に)

[RFG] 行動不変条件の変更。実行された動作と API (インターフェース) を保持

[CHG] 仕様/要件の変更を表すあらゆるものの実装

[FIX] コーディングの背後にある意図に準拠するように動作を変更する可能性のある変更。

次に、git-wise で行う必要があるのは次のとおりです。

  git checkout <bad commit SHA1> -b CULPRIT

これにより、「CULPRIT」ブランチが作成されます。次の手順の多くの退屈な繰り返しを実行する必要がある場合があるため、これを常に参照として保持します. 補足として、途中で部分参照を保持しておくと役立ちます(ブランチまたはタグとして)。

  git reset HEAD^ --mixed

これにより、コミットからのすべての変更がステージングされていない変更のパッチとして前のコミットに適用されたかのように、コミットが取り消されます。次に、

  git add --patch

これらの変更のサブセットを変更できます。[s]plit オプションを使用して、行ごとに変更を個別に選択することを躊躇しないでください。場合によっては、必要な変更を手動で選択するエディションを避けられないことがあります。そして、上記で提案した NEW、RFG、CHG、FIX スキームで分割された複数のコミットとして再ステージングし、必要な数のコミットを書き直します。

次の点に注意してください。

  • コンパイルされない新しいコミットのステージング
  • 「些細な」実行時エラー (たとえば、segfault など) を生成する新しいコミットのステージング
  • 物事を機能させるために組み合わせる必要があるサブコミット

...目標はバイセクトを機能させることだからです。さらに、新しいコミットが git diff によって古いコミットと同じであることを確認し、新しい HEAD コミットが CULPRIT に対して行われ、それ以上の変更が導入されていないことを確認します。

これは最初は苦痛であり、多くの練習が必要ですが、これが十分にできるようになると、チーム全体が崇拝するデバッグの神になり、小さなコミットの福音を NEW の形で広めることができます。 CHG、RFG、FIX。

于 2013-10-17T13:23:35.020 に答える
3

そのコミットからいつでもブランチを作成し、コミットをより小さなコミットに分割し、そこから二分割に進むことができます。

git bisectまた、それは問題につながる変更を絞り込むための単なるツールであることを忘れないでください。問題を分析し、バグを見つけ、修正を考え出す必要がなくなるわけではありません。

于 2013-10-17T13:10:01.090 に答える
1

悪いコミットにはいくつかのファイルしかなかったので、私はやや単純な方法を選択しました。受け入れられた答えから引き出して、これが私がやったことです:

1) コミットのステージングされていないバージョンを準備します。

git checkout <bad commit SHA1> -b CULPRIT
git reset HEAD^ --mixed

2) 別のファイルをステージングします。

git add <filename>

3) ステージングされたファイルをそのままにして、残りのファイルを隠します。

git stash --keep-index

4) それでもバグが表示されない場合:

git stash pop

5) バグが表示されるまで、手順 2、3、および 4 を繰り返します。つまり、前にステージングされたファイルが原因です。

犯人ファイルにはいくつかの無関係な変更があったため、削除プロセスを続行することにしましたが、今回はコード行 (または「ハンク」) レベルで下に移動します。

6) 個々のコード ハンクを原因ファイルにステージングします。

add --patch <culprit filename>

7) バグが表示されるまでステップ 3 と 4 を繰り返します。つまり、前にステージングされたハンクが原因です。

git bisect を使用してもう少しエレガントにこれを行うこともできたと思いますが、問題のあるコミットには影響を受けるファイルが 7 つしかなかったため、手動で削除することにしました。悪いコードが見つかったら、ローカルの CULPRIT ブランチを削除しました。

于 2016-10-10T13:47:35.043 に答える