rsync の --link-dest オプションはファイル時間のためリンクしません

rsync の --link-dest オプションはファイル時間のためリンクしません

次のテストケースを考えてみましょう。

mkdir a
echo 'blah' > a/test
mkdir b
echo 'blah' > b/test

rsync -r --link-dest=/tmp/b /tmp/a/ /tmp/c

予想どおり、rsync はc/testのハードリンクを作成しますb/test( の参照カウントに注意してください2)。

# ls -l c/test
-rw-r--r-- 2 root root 16 Jan  6 19:43 test

次にこれを見てください:

rm -r c # start over
touch b/test
rsync -r --link-dest=/tmp/b /tmp/a/ /tmp/c

ハードリンクは作成されません:

# ls -l c/test
-rw-r--r-- 1 root root 16 Jan  6 19:50 test

マニュアルページ(強調は筆者による)

ファイルはすべての点で同一である必要があります保存されたファイルを相互にリンクするために必要な属性 (権限、所有権など)。

しかし、デフォルトではファイル時間は保存されたしたがって、ここでは違いはないはずです。

何が起こっているのでしょうか? これはバグでしょうか? どうすればいいでしょうか?

私の目標は、すべての同一ファイルをハードリンクすることで、リポジトリの多数のブランチをホストする継続的インテグレーション サーバーのスペースを節約することです。したがって、実際のコマンドは次のようになります。つまり
rsync -r --link-dest=/ci/master /ci-runner/build/ /ci/branch-123
時刻は気にしないので、touchの前にすべてを現在の時刻に ing することを考えましたrsyncが、これはやや粗雑な解決策であり、また touch は再帰的に動作しないようです。

答え1

これは、ファイルのサイズとタイムスタンプに基づいてファイルの転送を決定する rsync の「クイック チェック」アルゴリズムの結果です。詳細は次のとおりですman rsync

rsync は、サイズまたは最終更新時刻が変更されたファイルを検索する「クイック チェック」アルゴリズム (デフォルト) を使用して、転送する必要があるファイルを検索します。クイック チェックでファイルのデータを更新する必要がないことが示された場合、その他の保存属性 (オプションで要求される) の変更は、宛先ファイルに直接行われます。

選択肢があります:

  • タイムスタンプを無視し、変更されたサイズのみに基づいてファイルを転送する場合は、--size-onlyオプションを使用できます。

    rsyncこれは、変更によってファイルのサイズがそのままになった場合、変更されたファイルは転送されないことを意味することに注意してください。

  • rsync代わりに、ファイルの内容が実際に同一であるかどうかをチェックしたい場合は、 を使用します--checksum。これにより、大幅な速度低下が発生する可能性があります。

「クイック チェック」アルゴリズムは、速度と精度の間で一般的に適切な妥協点となるため、デフォルトになっています。

関連情報