Gitはファイル名ではなく、ファイルの内容を追跡します。したがって、コンテンツを変更せずにファイルの名前を変更することは、gitが簡単に検出できます。(Gitはトラッキングされないが、実行が検出されれ、使用git mv
またはgit rm
とgit add
実質的に同じです。)
ファイルがリポジトリに追加されると、ファイル名はツリーオブジェクト内にあります。実際のファイルの内容は、バイナリラージオブジェクト(blob)としてリポジトリに追加されます。Gitは、同じコンテンツを含む追加のファイルに別のblobを追加しません。実際、Gitはコンテンツをファイルシステムに保存しているため、ハッシュの最初の2文字がディレクトリ名で、残りがその中のファイルの名前であるため、Gitではできません。したがって、名前の変更を検出することは、ハッシュを比較することです。
名前が変更されたファイルへの小さな変更を検出するために、Gitは特定のアルゴリズムとしきい値制限を使用して、これが名前の変更かどうかを確認します。たとえば、の-M
フラグを確認してくださいgit diff
。merge.renameLimit
(マージ中に名前変更の検出を実行するときに考慮するファイルの数)などの構成値もあります。
gitが同様のファイルをどのように処理するか(つまり、どのファイル変換が名前変更と見なされるか)を理解するには、上記のように、使用可能な構成オプションとフラグを調べます。あなたはその方法を考慮する必要はありません。gitが実際にこれらのタスクを実行する方法を理解するには、テキストの違いを見つけるためのアルゴリズムを調べ、gitソースコードを読んでください。
アルゴリズムは、diff、merge、logの目的にのみ適用されます。それらはgitがアルゴリズムを保存する方法には影響しません。ファイルコンテンツの小さな変更は、新しいオブジェクトが追加されることを意味します。そのレベルでは、デルタや差分は発生していません。もちろん、後で、オブジェクトはデルタがパックファイルに格納されている場所にパックされる可能性がありますが、これは名前変更の検出とは関係ありません。