sync: --fix-case flag to rename case insensitive dest - fixes #4854

Before this change, a sync to a case insensitive dest (such as macOS / Windows)
would not result in a matching filename if the source and dest had casing
differences but were otherwise equal. For example, syncing `hello.txt` to
`HELLO.txt` would result in the dest filename remaining `HELLO.txt`.
Furthermore, `--local-case-sensitive` did not solve this, as it actually caused
`HELLO.txt` to get deleted!

After this change, `HELLO.txt` is renamed to `hello.txt` to match the source,
only if the `--fix-case` flag is specified. (The old behavior remains the
default.)
This commit is contained in:
nielash
2023-10-08 22:59:22 -04:00
parent 88e516adee
commit 11afc3dde0
5 changed files with 91 additions and 0 deletions

View File

@@ -2197,6 +2197,39 @@ func TestSyncIgnoreCase(t *testing.T) {
r.CheckRemoteItems(t, file2)
}
// Test --fix-case
func TestFixCase(t *testing.T) {
ctx := context.Background()
ctx, ci := fs.AddConfig(ctx)
r := fstest.NewRun(t)
// Only test if remote is case insensitive
if !r.Fremote.Features().CaseInsensitive {
t.Skip("Skipping test as local or remote are case-sensitive")
}
ci.FixCase = true
// Create files with different filename casing
file1a := r.WriteFile("existing", "potato", t1)
file1b := r.WriteFile("existingbutdifferent", "donut", t1)
file1c := r.WriteFile("subdira/subdirb/subdirc/hello", "donut", t1)
file1d := r.WriteFile("subdira/subdirb/subdirc/subdird/filewithoutcasedifferences", "donut", t1)
r.CheckLocalItems(t, file1a, file1b, file1c, file1d)
file2a := r.WriteObject(ctx, "EXISTING", "potato", t1)
file2b := r.WriteObject(ctx, "EXISTINGBUTDIFFERENT", "lemonade", t1)
file2c := r.WriteObject(ctx, "SUBDIRA/subdirb/SUBDIRC/HELLO", "lemonade", t1)
file2d := r.WriteObject(ctx, "SUBDIRA/subdirb/SUBDIRC/subdird/filewithoutcasedifferences", "lemonade", t1)
r.CheckRemoteItems(t, file2a, file2b, file2c, file2d)
// Should force rename of dest file that is differently-cased
accounting.GlobalStats().ResetCounters()
err := Sync(ctx, r.Fremote, r.Flocal, false)
require.NoError(t, err)
r.CheckLocalItems(t, file1a, file1b, file1c, file1d)
r.CheckRemoteItems(t, file1a, file1b, file1c, file1d)
}
// Test that aborting on --max-transfer works
func TestMaxTransfer(t *testing.T) {
ctx := context.Background()