Add optional hash-based directories for torrent payloads - #24742
Add optional hash-based directories for torrent payloads #24742gl00ten wants to merge 4 commits into
Conversation
|
I like the idea, but don't really like the implementation.
Also maybe just appending full hash but without the |
This idea has also crossed my mind. |
|
Sure, I can move it into the existing content-layout dropdown. The qb- was meant to show that qBittorrent added the suffix, but removing it would make the scheme easier for other clients to adopt. My only concern with using the full hash is path length: v1 adds 40 characters and v2 up to 64, which may cause problems with long names, especially on Windows. I think 12 hex characters is more than enough in practice, with roughly a 3.55e-15 (1 in trillions) collision probability. And then only for torrents with the same payload name. I also tested it with cross-seeding, and it worked correctly: |
When enabled, newly added torrents are stored under a stable top-level directory named from the torrent and a short torrent-ID hash (for example "Show [qb-a19f83c275d1]"). This avoids same-name path collisions without scanning other torrents. Existing torrents are unchanged until the user applies the conversion from the transfer list. If the target hash directory already exists, it is replaced entirely after confirmation. Per-torrent preserve original name remains available for intentional cross-seeding. Closes qbittorrent#12842
qBittorrent enables long paths on Windows (allows up to 10k path length), so it shouldn't be a problem. The problem could be with the dir name itself though.
Maybe. But either way you need to ensure that the combined name is shorter than 255 chars/bytes depending on a platform, and truncate torrent names somehow if necessary. qBittorrent/src/base/utils/fs.cpp Lines 243 to 246 in 3c2a58e qBittorrent/src/base/utils/fs.cpp Lines 255 to 258 in 3c2a58e Or maybe keeping only hashes as names is also an option. |
Fold hash naming into TorrentContentLayout::UniqueSubfolder, always keep the full 12-hex tag (truncate the name from the end to fit platform filename limits), and reduce right-click migrate to rename-if-free only.
9ff82ec to
ceb7aa1
Compare
On convert, if the destination unique folder is already present, ask for confirmation then proceed with normal per-file renames (matching paths may be overwritten; unrelated files stay). Do not delete the destination directory. Layout is still set only after all renames succeed.
Refuse conversion when any destination file path already exists (libtorrent may not overwrite). Empty unique directories and unrelated files are fine. Partial retries map under the unique root without double-wrapping. Drop setName on success and remove unreleased append_hash resume compatibility.
Fixes:
#12842
Summary
This PR adds an opt-in option to give each torrent payload a deterministic top-level directory based on the torrent hash.
For example:
The goal is to prevent unrelated torrents with the same payload name from writing into the same directory.
Screenshots:
New option in settings:

New item in right click menu:

New style for directories. Guarantees uniqueness and sameness across sessions.

New option to preserve original name (for cross seeding) and what not:

Behaviour
When hash naming is enabled:
Existing torrents can be converted through the context-menu action.
If the target hashed directory already exists, qBittorrent warns the user that the entire directory will be permanently deleted and replaced. Nothing is deleted unless the user confirms.
The existing directory is not merged and no alternative names such as
(1)are generated.Motivation
Two torrents can have the same top-level payload name while containing different data. When both use the same save location, their files may overlap or overwrite one another.
Adding a deterministic hash suffix gives every torrent a unique and predictable payload directory while keeping the original name recognisable.
(personally, I got tired of IO errors on torrents with the same name)
Testing
I manually tested:
Unit tests were also added for the payload-name generation logic, including single-file, multi-file, rootless, Unicode, long-name and idempotence cases.
Edit:
This also fixes the magnet-versus-.torrent naming inconsistency. Magnet links may initially have only a display name and incomplete metadata, but once the metadata is available, qBittorrent uses the torrent’s canonical name and torrent ID to generate the payload path. As a result, adding the same torrent through a magnet link or a .torrent file should produce the same deterministic hashed folder name instead of creating different directories based on the magnet display name. The only unrelated edge case is duplicate detection between unresolved v1-only and v2-only magnets for the same hybrid torrent, since qBittorrent cannot know they refer to the same torrent until metadata is received.