diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e15da9f1..519a70083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed permissions restore in latest backup version - Incremental OneDrive backups could panic if the delta token expired and a folder was seen and deleted in the course of item enumeration for the backup. +- Incorrectly moving subfolder hierarchy from a deleted folder to a new folder at the same path during OneDrive incremental backup. ## [v0.6.1] (beta) - 2023-03-21 diff --git a/src/internal/connector/onedrive/collections.go b/src/internal/connector/onedrive/collections.go index a482de3d7..411154891 100644 --- a/src/internal/connector/onedrive/collections.go +++ b/src/internal/connector/onedrive/collections.go @@ -378,24 +378,18 @@ func (c *Collections) Get( continue } - // Set all folders in previous backup but not in the current - // one with state deleted - modifiedPaths := map[string]struct{}{} + // Set all folders in previous backup but not in the current one with state + // deleted. Need to compare by ID because it's possible to make new folders + // with the same path as deleted old folders. We shouldn't merge items or + // subtrees if that happens though. + foundFolders := map[string]struct{}{} - for _, p := range c.CollectionMap[driveID] { - if p.FullPath() != nil { - modifiedPaths[p.FullPath().String()] = struct{}{} - } + for id := range c.CollectionMap[driveID] { + foundFolders[id] = struct{}{} } for fldID, p := range oldPaths { - if _, ok := paths[fldID]; ok { - continue - } - - if _, ok := modifiedPaths[p]; ok { - // Original folder was deleted and new folder with the - // same name/path was created in its place + if _, ok := foundFolders[fldID]; ok { continue } diff --git a/src/internal/connector/onedrive/collections_test.go b/src/internal/connector/onedrive/collections_test.go index 25448abd6..c12d1b390 100644 --- a/src/internal/connector/onedrive/collections_test.go +++ b/src/internal/connector/onedrive/collections_test.go @@ -1850,8 +1850,13 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() { }, }, expectedCollections: map[string]map[data.CollectionState][]string{ - rootFolderPath1: {data.NewState: {}}, - expectedPath1("/folder"): {data.NewState: {"folder2", "file"}}, + rootFolderPath1: {data.NewState: {}}, + expectedPath1("/folder"): { + // Old folder path should be marked as deleted since it should compare + // by ID. + data.DeletedState: {}, + data.NewState: {"folder2", "file"}, + }, }, expectedDeltaURLs: map[string]string{ driveID1: delta,