mirror of
https://github.com/syncthing/syncthing.git
synced 2024-11-16 10:28:49 -07:00
lib/model: Fix case-only renames on pull (#6978)
This commit is contained in:
parent
780fb3bac1
commit
56d48d341f
@ -945,16 +945,26 @@ func (f *sendReceiveFolder) renameFile(cur, source, target protocol.FileInfo, sn
|
||||
// Check that the target corresponds to what we have in the DB
|
||||
curTarget, ok := snap.Get(protocol.LocalDeviceID, target.Name)
|
||||
switch stat, serr := f.fs.Lstat(target.Name); {
|
||||
case serr != nil && fs.IsNotExist(serr):
|
||||
if !ok || curTarget.IsDeleted() {
|
||||
break
|
||||
}
|
||||
scanChan <- target.Name
|
||||
err = errModified
|
||||
case serr != nil:
|
||||
// We can't check whether the file changed as compared to the db,
|
||||
// do not delete.
|
||||
err = serr
|
||||
var caseErr *fs.ErrCaseConflict
|
||||
switch {
|
||||
case errors.As(serr, &caseErr):
|
||||
if caseErr.Real != source.Name {
|
||||
err = serr
|
||||
break
|
||||
}
|
||||
fallthrough // This is a case only rename
|
||||
case fs.IsNotExist(serr):
|
||||
if !ok || curTarget.IsDeleted() {
|
||||
break
|
||||
}
|
||||
scanChan <- target.Name
|
||||
err = errModified
|
||||
default:
|
||||
// We can't check whether the file changed as compared to the db,
|
||||
// do not delete.
|
||||
err = serr
|
||||
}
|
||||
case !ok:
|
||||
// Target appeared from nowhere
|
||||
scanChan <- target.Name
|
||||
|
@ -1242,6 +1242,45 @@ func TestPullTempFileCaseConflict(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullCaseOnlyRename(t *testing.T) {
|
||||
m, f := setupSendReceiveFolder()
|
||||
defer cleanupSRFolder(f, m)
|
||||
|
||||
// tempNameConfl := fs.TempName(confl)
|
||||
|
||||
name := "foo"
|
||||
if fd, err := f.fs.Create(name); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if _, err := fd.Write([]byte("data")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fd.Close()
|
||||
}
|
||||
|
||||
must(t, f.scanSubdirs(nil))
|
||||
|
||||
cur, ok := m.CurrentFolderFile(f.ID, name)
|
||||
if !ok {
|
||||
t.Fatal("file missing")
|
||||
}
|
||||
|
||||
deleted := cur
|
||||
deleted.SetDeleted(myID.Short())
|
||||
|
||||
confl := cur
|
||||
confl.Name = "Foo"
|
||||
confl.Version = confl.Version.Update(device1.Short())
|
||||
|
||||
dbUpdateChan := make(chan dbUpdateJob, 2)
|
||||
scanChan := make(chan string, 2)
|
||||
snap := f.fset.Snapshot()
|
||||
defer snap.Release()
|
||||
if err := f.renameFile(cur, deleted, confl, snap, dbUpdateChan, scanChan); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func cleanupSharedPullerState(s *sharedPullerState) {
|
||||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
Loading…
Reference in New Issue
Block a user