[Feature] Let immich upload check what's already on the server without uploading (e.g. --no-upload)
#31624
Replies: 4 comments 4 replies
|
This discussion has automatically been closed as it is likely a duplicate. We get a lot of duplicate threads each day, which is why we ask you in the template to confirm that you searched for duplicates before opening one. If you're sure this is not a duplicate, please leave a comment and we will reopen the thread if necessary. |
|
I did search before posting, and again now: I can't find a prior request for this. The related open issues I found (#29349, #30491) are about the web UI's duplicate-detection tool, which is a different feature — this asks for a way to run Happy to be pointed at the existing thread if there is one; the bot didn't say which it matched. |
|
--dry-run already does what you want. |
|
What I'm after is the other half: skip the upload but do prune the confirmed duplicates. Today I did consider extending |
Uh oh!
There was an error while loading. Please reload this page.
I have searched the existing feature requests, both open and closed, to make sure this is not a duplicate request.
The feature
immich upload --deleteand--delete-duplicatesonly ever run as a side effect of an upload, so checking a directory against the server and acting on what's already there means uploading every new file in it first. There's no way to ask "which of these do I already have?" and act on the answer without that.uploadBatchalready computes exactly the split this would need (packages/cli/src/commands/asset.ts:69–78):checkForDuplicatesalready produces thenewFiles/duplicatessplit;deleteFilesalready knows how to deleteduplicateswhen--delete-duplicatesis set. The only thing standing between "check" and "act on what the server already has" is theuploadFiles(newFiles, options)call on line 71. This is proposed as a small flag, not a new subsystem: skip that one call, leavenewFileson disk and reported instead of uploaded, and let--delete-duplicates(and--json-outputreporting) act onduplicatesexactly as they do today.Flag naming — three options, with trade-offs:
--no-upload: matches the existing negated-boolean convention already used in this same command for--no-progress(packages/cli/src/index.ts:89), so it reads consistently next to the other flags. Downside: it reads a little oddly stacked against the subcommand's own name (immich upload --no-upload). One caveat I ran into while implementing it: commander enables a boolean option on env-var presence, so the existing--no-progressprecedent meansIMMICH_PROGRESS_BAR=falseactually disables progress bars rather than enabling them. I named the new variableIMMICH_NO_UPLOAD, after the flag rather than after the negated noun, so presence-means-on reads correctly. ThatIMMICH_PROGRESS_BARbehaviour looks like a separate pre-existing bug; happy to file it separately if it is not already known.--check-only: states the intent more directly, without the double-negative-with-the-subcommand-name feel. Downside: introduces a second name for the same underlying idea ("upload" vs. "check"), and could later be conflated with a hypothetical checksum-only or metadata-only mode.--dry-run: rejected.--dry-runalready exists and already suppresses both the upload and the deletion (deleteFilesshort-circuits underoptions.dryRunatasset.ts:469–472). Extending it would change already-documented behaviour rather than add new behaviour, and would remove the "actually delete confirmed duplicates" outcome this request is for.My preference is
--no-upload, for consistency with--no-progress, but I don't feel strongly against--check-onlyand would defer to the maintainers.Prior art. I've been running a small standalone tool alongside the CLI that does exactly this: same checksum-based check against
/assets/bulk-upload-check, no upload capability at all. A few of its safety choices are worth naming here, split into what's actually in scope for this flag and what isn't:uploadFilescall above —--delete-duplicatesand--deletealready do the rest server-side.deleteFiles/findSidecaralready does this (asset.ts:447–457,489–493).--delete/--delete-duplicatesdo across the whole CLI today (not specific to a "don't upload" flag), would change already-shipped behaviour, and deserves its own proposal and maintainer discussion rather than riding in on this one. I'm not proposing it here.Platform
@immich/cli, which is released alongside the server platform in this repo; there's no dedicated CLI checkbox)Working implementation
I have this implemented and running, but I have deliberately not opened a PR — I would rather check the idea is wanted before asking anyone to review it. Branch: https://github.com/DevJake/immich/tree/feat/cli-no-upload (one commit, cherry-picks cleanly onto
main).Shape of it:
--no-uploadgates theuploadFilescall, beside the existingdryRunshort-circuit it mirrors.checkForDuplicates,updateAlbums, anddeleteFilesare untouched.--delete(nothing is uploaded, so it is always a no-op) and with--skip-hash(skips the duplicate check, so the command could neither upload nor delete anything). Both are refused by commander rather than silently doing nothing.--dry-run,--album/--album-name, and--watch. Albums work because duplicates carry real server asset ids.build,check,lint --max-warnings 0, andformatall pass.I have been running it against my own instance (~624 GiB library) to prune a 20 GB+ directory of mixed new and already-stored media, which is the use case that prompted this.
Happy to adapt the naming, the conflict choices, or the reporting to whatever you would prefer, or to drop it if this is not a direction you want the CLI to go.
LLM usage
Since the PR template asks and it seems only fair to volunteer it here too: the implementation, its tests, and this write-up were produced by an AI coding agent working under my direction and review. I verified the code paths, ran the gate, and did the real-world testing above myself.
All reactions