dashboard / erock/pico / fix(rsync): delete largest path first #98 rss

open · opened on 2025-12-19T01:28:25Z by erock
Help
checkout latest patchset:
ssh pr.pico.sh print pr-98 | git am -3
checkout any patchset in a patch request:
ssh pr.pico.sh print ps-X | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 98
add review to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add --review 98
accept PR:
ssh pr.pico.sh pr accept 98
close PR:
ssh pr.pico.sh pr close 98

Logs

erock created pr with ps-178 on 2025-12-19T01:28:25Z
erock added ps-179 on 2025-12-19T01:39:08Z

Patchsets

ps-178 by erock on 2025-12-19T01:28:25Z
Range Diff ↕ rd-179
1: f8ad8c5 = 1: f8ad8c5 fix(rsync): delete largest path first
-: ------- > 2: 0d69224 chore: add tests
ps-179 by erock on 2025-12-19T01:39:08Z

Patchset ps-178

Back to top
+8 -0 pkg/send/protocols/rsync/rsync.go link
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
diff --git a/pkg/send/protocols/rsync/rsync.go b/pkg/send/protocols/rsync/rsync.go
index a50d0c2..765142e 100644
--- a/pkg/send/protocols/rsync/rsync.go
+++ b/pkg/send/protocols/rsync/rsync.go
@@ -153,6 +153,14 @@ func (h *handler) Remove(willReceive []*rsyncutils.ReceiverFile) error {
 		}
 	}
 
+	// Sort by path depth descending so children are deleted before parents.
+	// This ensures directories are empty before we try to remove them.
+	slices.SortFunc(toDelete, func(a, b string) int {
+		depthA := strings.Count(a, "/")
+		depthB := strings.Count(b, "/")
+		return depthB - depthA
+	})
+
 	var errs []error
 
 	for _, file := range toDelete {