2011-10-29 11 views
75

ウィキペディアは自動リネーム検出説明:リビジョンNでファイルを与え、gitはリネームの検出のために類似のファイルをどのように検出しますか?

簡単に言うと、 リビジョンN-1に同じ名前のファイルは、デフォルトの祖先です。しかし、リビジョンN-1に という名前のファイルがない場合、GitはリビジョンN-1にある のファイルのみを検索し、と非常に似ていますです。

名前の変更の検出は、同様のファイル検出に変わりはありません。そのアルゴリズムはどこに文書化されていますか?どのような種類の変換が自動的に検出されるのかを知ることは良いことです。

答えて

75

Gitはファイル名ではなくファイルの内容を追跡します。したがって、内容を変更せずにファイルの名前を変更することは、gitが検出するのは簡単です。 (Gitは追跡が、検出実行しない; git mv又はgit rmgit addが効果的に同じである使用)

ファイルをリポジトリに追加されると、ファイル名がツリーオブジェクトです。実際のファイルの内容は、バイナリラージオブジェクト(blob)としてリポジトリに追加されます。 Gitは、同じコンテンツを含む追加のファイルに別のBLOBを追加しません。実際、Gitはコンテンツがファイルシステムに格納されているので、ハッシュの最初の2文字はディレクトリ名であり、残りはファイル名です。したがって、名前の変更を検出するには、ハッシュを比較する必要があります。

名前が変更されたファイルの小さな変更を検出するために、Gitは特定のアルゴリズムとしきい値の制限を使用して名前の変更を確認します。たとえば、git diffのフラグ-Mを見てください。 merge.renameLimit(マージ中に名前の変更を検出するときに考慮するファイルの数)などの構成値もあります。

類似ファイル(つまり、どのファイル変換が名前変更と見なされるか)を扱う方法を理解するには、前述のように、使用可能な設定オプションとフラグを調べてください。あなたは方法で考慮する必要はありません。 gitが実際にこれらのタスクをどのように実行するかを理解するには、テキストの違いを見つけるアルゴリズムを見て、gitのソースコードを読んでください。

アルゴリズムは差分、マージ、ログの目的にのみ適用され、gitの格納方法には影響しません。ファイル内容のわずかな変更は、新しいオブジェクトが追加されたことを意味します。そのレベルではデルタや差分は起こっていません。もちろん、後で、デルタがパックファイルに格納されているオブジェクトはパックされるかもしれませんが、名前の変更の検出には関係しません。

+2

素晴らしいサマリー、ありがとうございます。 – mahemoff

+2

+1 ** **単語**を強調するために+1 – akhyar

+28

_ "あなたは方法を考慮する必要はありません" _ - 私はそれが質問だと思った? – bain

4

テキスト間の類似性を検出する多くのアルゴリズムがあります。バージョン管理システムでは、2つのバージョン間の差異だけを保存するためにバージョン管理システムがこれらを使用することがよくあります。 WinMergeのようなツールは、行内であっても差異を検出するのに十分なほどスマートなので、これらのアルゴリズムがこの名前変更の検出に使用されない理由は見当たりません。

ここにはalgorithms to detect similar textsに関する説明があります。これらのアルゴリズムの中には、自然言語用に最適化されているものもあれば、ソースコードでうまくいくものもありますが、本質的には非常に似ています。

関連する問題