Skip to content

Preserve file attributes during move/copy operations - #1932

Open
wirwolf wants to merge 3 commits into
qarmin:masterfrom
wirwolf:issues_1321
Open

wirwolf wants to merge 3 commits into
qarmin:masterfrom
wirwolf:issues_1321

Conversation

@wirwolf

@wirwolf wirwolf commented May 1, 2026

Copy link
Copy Markdown

Problem

When files are moved from Czkawka/Krokiet using the move action, moved files receive the current modification time instead of keeping their original metadata. This is especially problematic for photo and video collections, where mtime is commonly used for sorting and organization.

Reported in: #1321

What was changed

The original approach of setting copy_attributes = true on fs_extra options was not possible — fs_extra 1.3.0 does not have this field. fs_extra has been removed from both crates and replaced with a stdlib-based implementation that correctly preserves attributes.

czkawka_gui/src/connect_things/connect_button_move.rs

  • Replaced fs_extra::dir::move_dir and fs_extra::file::move_file with a custom move_item_preserving_attrs function.
  • On the same filesystem, uses std::fs::rename — atomic, preserves all attributes with zero overhead.
  • On cross-device moves, falls back to copy_item_preserving_attrs + delete, which restores permissions and timestamps (mtime, atime) after copying.

krokiet/src/file_actions/connect_move.rs

  • Replaced fs_extra::dir::copy and fs_extra::file::copy with a custom copy_with_attrs function.
  • For files: uses std::fs::copy (preserves permissions on Unix) followed by std::fs::FileTimes to restore mtime and atime.
  • For directories: recursively applies the same logic to every entry.

czkawka_gui/Cargo.toml / krokiet/Cargo.toml

  • Removed fs_extra dependency from both crates.

Expected behavior

When selected duplicate files or folders are moved or copied, their file attributes are preserved:

  • modification time (mtime) stays unchanged;
  • access time (atime) stays unchanged;
  • file permissions are preserved.

Why this matters

Changing modification time during move operations breaks workflows where users rely on filesystem timestamps, for example:

  • organizing photos and videos by date;
  • sorting media collections;
  • preserving imported file metadata;
  • moving duplicates to a quarantine/review directory before deletion.

@KunalScriptz

Copy link
Copy Markdown

Great work @wirwolf

if src.is_dir() { std::fs::remove_dir_all(src) } else { std::fs::remove_file(src) }
}

fn copy_item_preserving_attrs(src: &Path, dst: &Path) -> std::io::Result<()> {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy/move functions should be moved to czkawka_core, because this is thing duplicated between all gui backends(and in future maybe even CLI will add this)

} else {
std::fs::copy(src, dst)?;
let times = std::fs::FileTimes::new().set_accessed(metadata.accessed()?).set_modified(metadata.modified()?);
std::fs::OpenOptions::new().write(true).open(dst)?.set_times(times)?;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably for readonly files will throw an error - don't know this for sure, so test, testing this potential problem should be added to PR

}

fn move_item_preserving_attrs(src: &Path, dst: &Path) -> std::io::Result<()> {
if std::fs::rename(src, dst).is_ok() {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for all rename errors, we should use copy fallback.

I think, that only in case of ErrorKind::CrossesDevices, this should try to move file/folder with alternative method

@luzpaz

luzpaz commented Jun 12, 2026

Copy link
Copy Markdown

Hi @wirwolf, are you still planning to work on this ?

@wirwolf

wirwolf commented Jun 15, 2026 •

Copy link
Copy Markdown
Author

Hi @wirwolf, are you still planning to work on this ?

Hey. Maybe a little bit later. I build your project locally, run it on my NAS and find all issues in my data. If you ask about comments for code formatting - i add finishing this MR to my to-do list

PS: Also, if it's interesting, I run this project in a Docker container to run on a remote server and control the application on a browser. Its very comfortable

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants