4

機能ブランチで大規模なコードベースの名前を変更/再編成し、リファクタリングするというやや面倒なプロセスを経たところです。プロセス中に、gitが名前の変更を認識できるように、いくつかの変更を加えてインクリメンタルチェックインを実行しました。ただし、この機能を開発ブランチにマージしているので、Gitはこれらの名前の変更を「記憶」しておらず、代わりに削除/追加として扱っているようです。別の名前変更しきい値を設定しても効果がないようです。

gitは、ファイルの名前が変更/移動されたことを前回のコミットから知る必要がありますか?

編集 奇妙なことに、devを機能ブランチにマージすると、その逆ではなく、gitが名前の変更を認識しているように見えます。私はこれを行うことになり、次にdevを機能ブランチの先頭にリセットしました。この場合、マージの方向は重要ですか?

4

2 に答える 2

2

gitは実際には名前の変更を追跡しません。Git FAQに記載されているように、名前の変更を検出するために「名前変更検出」アルゴリズムに依存しています。

Git は、さまざまなワークフローと相互運用する必要があります。たとえば、一部の変更は、名前変更情報が利用できない可能性があるパッチから発生する可能性があります。明示的な名前変更の追跡に依存すると、まったく同じことを行った 2 つのツリーをマージすることができなくなります。ただし、一方はパッチ (作成/削除) として実行し、もう一方は他のヒューリスティックを使用して実行しました。

2 つ目の注意点として、名前の変更の追跡は、ツリー内でコンテンツがどのように移動するかを追跡する特殊なケースにすぎません。場合によっては、関数がいつ追加されたか、別のファイルに移動されたかを照会することに関心があるかもしれません。必要なときにこの情報を再作成する機能のみに依存することで、Git はツリーの変化を追跡するためのより柔軟な方法を提供することを目指しています。

ただし、これは、Git が名前の変更をサポートしていないという意味ではありません。Git の diff 機構は、名前の自動検出をサポートしています。これは、コマンドの git-diff-* ファミリーへの「-M」スイッチによって有効になります。名前変更検出機構は git-log(1) および git-whatchanged(1) によって使用されるため、たとえば、'git log -M' はコミット履歴と名前変更情報を提供します。Git は、名前変更を伴う制限付きのマージもサポートしています。責任を割り当てるための 2 つのツール git-blame(1) と git-annotate(1) はどちらも、自動名前変更検出コードを使用して名前変更を追跡します。

非常に特殊なケースとして、「git log」バージョン 1.5.3 以降には「--follow」オプションがあり、単一のパスが指定されたときに名前の変更を追跡できます。

したがって、ファイルをリファクタリングして名前を変更した場合、その古いファイルとの類似性は非常に小さくなり、その結果のstatusorlogは、ファイルが削除されてから追加されたことを示している可能性があります。

いくつかのオプションは、リファクタリングによっても名前の変更を検出するのに役立つ場合があります。

  • -M<n>

    名前の変更を検出します。n が指定されている場合、それは類似性指標 (つまり、ファイルのサイズと比較した追加/削除の量) のしきい値です。たとえば、-M90% は、ファイルの 90% 以上が変更されていない場合、git が削除/追加のペアを名前変更と見なす必要があることを意味します。

  • -w

    空白の量の変化を無視します。これは、行末の空白を無視し、1 つ以上の空白文字の他のすべてのシーケンスを同等と見なします。

  • -B<n>

    完全な書き換え変更を削除と作成のペアに分割します。

-Bファイルが変更されていても、ファイルを名前変更ソースと見なすことができるため、便利です。たとえば、 の 90% を に移動し、一部の機能を に残した場合、名前の変更が検出foo.cbar.cfoo.cます。

于 2012-09-21T04:54:18.220 に答える