16

Git でファイルの名前を変更することについて以前 質問され ましたが、特定の問題の解決策を見つけることができません。

複数のファイルを移動して編集しました (使用しませんでしたgit mv- 残念ながら、今では手遅れです)。同僚が同じファイルに独自の編集を加えて(移動せずに)私のリポジトリからプルすると、ファイルの新しい場所で私の変更が彼の変更と正常にマージされるようになりました。マージを成功させるには、これらが同じファイルであることを Git が認識している必要があります。

Git はこれを単独で解決できるほど賢いのでしょうか? 信じがたいようです。もしそうなら、特定のファイルの移動が Git によって確実に取得されるようにするにはどうすればよいでしょうか?たとえ内容が変更されていたとしても?

4

3 に答える 3

21

Git は実際にはリポジトリ内の名前変更を追跡しません。ファイルの名前を別の名前に変更したかどうかを判断するために差分ヒューリスティックを使用します。つまりgit mv、ファイルの内容を完全に置き換えた場合、それは名前変更とは見なされ、名前変更を検出するために for it を使用する必要はありません。git mv

例えば:

% mv d.txt e.txt
% git rm d.txt
rm 'd.txt'
% git add e.txt
% git commit -m"rename without git mv"
[master f70ae76] rename without git mv
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename d.txt => e.txt (100%)
% git diff --summary --find-renames HEAD~1 HEAD
 rename d.txt => e.txt (100%)

同様にgit mv、ファイルの名前が変更されるという意味ではなく、引き続き diff アルゴリズムが使用されます。

% git mv e.txt f.txt
% echo "Completely replacing f.txt" > f.txt
% git add f.txt
% git commit -m"git mv doesn't help here"
[master 068d19c] git mv doesn't help here
 2 files changed, 1 insertion(+), 14 deletions(-)
 delete mode 100644 e.txt
 create mode 100644 f.txt
% git diff --summary --find-renames HEAD~1 HEAD
 delete mode 100644 e.txt
 create mode 100644 f.txt
于 2012-10-08T16:16:22.177 に答える
8

デフォルトでは、コミット間でファイルが削除されるたびに、git は名前の変更をチェックします。手動で通知する必要はありません。実際にファイルを移動した場合 (手動で削除して再度追加するのではなく、git mv を使用)、ヒントは無視されます。パフォーマンス上の理由から、ヒューリスティックは常に実行されるわけではありません。ファイルを邪魔にならないように移動してから、元の名前で新しいファイルを追加すると、移動が検出されない場合があります。

論理的には、git は各リビジョンに存在していたツリーのみを保存することに注意してください。リビジョン間で行われた変更に関する追跡情報は保存しません。

検出されたものを確認したい場合は、-M( --find-renames) スイッチを使用git diffして名前の変更を表示できます。このスイッチは、ヒューリスティックもオンにします。これは、ヒューリスティックをトリガーしないコミットがある場合に役立ちます。

このヒューリスティック ベースのアプローチは、(別のアプローチが必要な場合) コミットを小さく自己完結型に保つ正当な理由です。これにより、git の作業が容易になります。

于 2012-10-08T16:15:50.360 に答える