名前変更の検出のために、gitはどのようにして同様のファイルを検出しますか?


91

ウィキペディアでは、自動名前変更検出について説明しています。

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

名前の変更の検出は、明らかに類似したファイルの検出に要約されます。そのアルゴリズムはどこかに文書化されていますか?どの種類の変換が自動的に検出されるかを知っておくと便利です。


回答:


92

Gitはファイル名ではなく、ファイルの内容を追跡します。したがって、コンテンツを変更せずにファイルの名前を変更することは、gitが簡単に検出できます。(Gitはトラッキングされないが、実行が検出されれ、使用git mvまたはgit rmgit add実質的に同じです。)

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

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

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

アルゴリズムは、diff、merge、logの目的にのみ適用されます。それらはgitがアルゴリズムを保存する方法には影響しません。ファイルコンテンツの小さな変更は、新しいオブジェクトが追加されることを意味します。そのレベルでは、デルタや差分は発生していません。もちろん、後で、オブジェクトはデルタがパックファイルに格納されている場所にパックされる可能性がありますが、これは名前変更の検出とは関係ありません。


57
「あなたはどのように考えられる必要はありません。」-それが問題だと思いましたか?
ベイン

2

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

ここでは、類似したテキストを検出するアルゴリズムについて説明します。これらのアルゴリズムには、自然言語向けに最適化されているものもあれば、ソースコードに適しているものもありますが、本質的には非常に似ています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.