Fix issues with renames (fixes #1302)

Extra comments explain current issues.
This commit is contained in:
Audrius Butkevicius 2015-01-30 14:32:59 +00:00
parent 8358fedaf4
commit 32af626630
1 changed files with 26 additions and 9 deletions

View File

@ -336,8 +336,9 @@ func (p *Puller) pullerIteration(ignores *ignore.Matcher) int {
df, ok := p.model.CurrentFolderFile(p.folder, file.Name)
// Local file can be already deleted, but with a lower version
// number, hence the deletion coming in again as part of
// WithNeed
if ok && !df.IsDeleted() {
// WithNeed, furthermore, the file can simply be of the wrong
// type if we haven't yet managed to pull it.
if ok && !df.IsDeleted() && !df.IsSymlink() && !df.IsDirectory() {
// Put files into buckets per first hash
key := string(df.Blocks[0].Hash)
buckets[key] = append(buckets[key], df)
@ -345,6 +346,9 @@ func (p *Puller) pullerIteration(ignores *ignore.Matcher) int {
}
case file.IsDirectory() && !file.IsSymlink():
// A new or changed directory
if debug {
l.Debugln("Creating directory", file.Name)
}
p.handleDir(file)
default:
// A new or changed file or symlink. This is the only case where we
@ -372,19 +376,25 @@ nextFile:
// Local file can be already deleted, but with a lower version
// number, hence the deletion coming in again as part of
// WithNeed
if !f.IsSymlink() && !f.IsDeleted() {
// WithNeed, furthermore, the file can simply be of the wrong type if
// the global index changed while we were processing this iteration.
if !f.IsDeleted() && !f.IsSymlink() && !f.IsDirectory() {
key := string(f.Blocks[0].Hash)
for i, candidate := range buckets[key] {
if scanner.BlocksEqual(candidate.Blocks, f.Blocks) {
// Remove the candidate from the bucket
l := len(buckets[key]) - 1
buckets[key][i] = buckets[key][l]
buckets[key] = buckets[key][:l]
lidx := len(buckets[key]) - 1
buckets[key][i] = buckets[key][lidx]
buckets[key] = buckets[key][:lidx]
// candidate is our current state of the file, where as the
// desired state with the delete bit set is in the deletion
// map.
desired := fileDeletions[candidate.Name]
// Remove the pending deletion (as we perform it by renaming)
delete(fileDeletions, candidate.Name)
p.renameFile(candidate, f)
p.renameFile(desired, f)
p.queue.Done(fileName)
continue nextFile
@ -410,11 +420,18 @@ nextFile:
doneWg.Wait()
for _, file := range fileDeletions {
if debug {
l.Debugln("Deleting file", file.Name)
}
p.deleteFile(file)
}
for i := range dirDeletions {
p.deleteDir(dirDeletions[len(dirDeletions)-i-1])
dir := dirDeletions[len(dirDeletions)-i-1]
if debug {
l.Debugln("Deleting dir", dir.Name)
}
p.deleteDir(dir)
}
return changed