From 9ab6686b98499c745024a474a71e3d99b6e14973 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 17 Sep 2026 13:58:25 +0200 Subject: a chain that deletes itself still gives back the file it displaced MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (on-conflict overwrite) trashes the file in the way; ยง7.4 promises undo restores it. Walking a file's log entries stopped dead at a permanent delete, so the displace written earlier in the same chain was never reached: the user's file stayed in the Trash, the refusal named only the file they did not care about, and krino log called the run undone. The displaced file is a different file, so it is offered as its own entry in the undo plan, keyed by its own path - the deleted file stays refused, since nothing of it can come back, and the copy or move that preceded the delete stays unreversed too (undoing a copy whose original was then deleted would destroy the last remaining copy). The accounting matched: every reversible step of a deleted file was subtracted, its displace included, so the run read (undone). Only what genuinely cannot come back is subtracted now. End to end, the scenario from the review: the only copy of a file is displaced by an incoming one that is then permanently deleted. before: archive/ empty, "(undone)", nothing offered after: archive/a.pdf restored, run reads partly undone --- cmd/krino/undo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmd/krino/undo.go') diff --git a/cmd/krino/undo.go b/cmd/krino/undo.go index 2d170a4..d21c40e 100644 --- a/cmd/krino/undo.go +++ b/cmd/krino/undo.go @@ -513,7 +513,7 @@ type undoRow struct { func undoRows(files []engine.UndoFile) []undoRow { var rows []undoRow for i, f := range files { - label := display(f.Dir + "/" + f.File) + label := display(f.Label()) if f.Refused != "" { rows = append(rows, undoRow{num: strconv.Itoa(i + 1), file: label, action: "refused: " + display(f.Refused)}) continue -- cgit v1.3