Skip to content

Conversation

Nykri
Copy link

@Nykri Nykri commented Jul 10, 2025

Description

This PR adds some small improvements to the immich upload command. It is particularly useful for big uploads of large libraries:

  • It adds hash caching :

    • Avoids rehashing all the files if you want to try different configs or check if everything has been uploaded in your whole library
    • Enables doing large uploads over multiple runs without loosing all progress
    • Stored in ~/.config/immich/hash-cache.json
  • Progress bar has been adapted to display file size instead of assets (which were hardly readable and usable for large uploads)

  • Concurrency number is automatically set to CPU cores - 1

  • Generates a unique album name when several directories have the same name. It does that using the parent folders names.
    This fix is especially useful for directory structure like:
    photos/
    ├── 2023/
    │ ├── Bretagne/ -> Album: 2023 Bretagne
    │ └── summer/
    │ └── beach/ -> Album: 2023 summer beach
    │ └── city/ -> Album: 2023 summer city
    ├── 2024/
    │ ├── Bretagne/ -> Album: 2024 Bretagne
    │ └── summer/
    │ └── beach/ -> Album: 2024 summer beach
    │ └── city/ -> Album: 2024 summer city

How Has This Been Tested?

Tested on a dummy file structure and on a real >1TB library upload.

Checklist:

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation if applicable
  • I have no unrelated changes in the PR.
  • I have confirmed that any new dependencies are strictly necessary.
  • I have written tests for new code (if applicable)
  • I have followed naming conventions/patterns in the surrounding code
  • All code in src/services/ uses repositories implementations for database calls, filesystem operations, etc.
  • All code in src/repositories/ is pretty basic/simple and does not have any immich specific logic (that belongs in src/services/)

This commit introduces several improvements to the CLI upload functionality:

1. Performance Improvements:

- Implement file hash caching with auto-save every 30s

- Set default concurrency to (CPU cores - 1)

- Add proper file stats caching to avoid redundant stat calls

2. Progress Bar UI Improvements:

- Add human-readable file sizes in progress bars

- Add human-readable ETA time format

- Improve ETA calculation with larger sample buffer

- Add proper cursor cleanup on SIGINT

- Show total size of files being processed

- Fix progress bar formatting

3. Album Name Formatting:

- Add --format-album-names flag to clean up album names

- Remove leading non-alphabetic characters

- Convert underscores and dashes to spaces

- Capitalize first letter

- Show album name changes in console

4. Code Organization & Fixes:

- Add @types/picomatch dependency

- Fix watch mode implementation with proper file matching

- Change -h flag to -s for skip-hash to avoid conflict

- Improve error handling and cleanup in hash operations

The main focus of these changes is to improve upload performance through caching and better resource utilization, especially beneficial for large uploads, while also providing a more informative progress display and cleaner album names.
Copy link
Contributor

github-actions bot commented Jul 10, 2025

Label error. Requires exactly 1 of: changelog:.*. Found: cli. A maintainer will add the required label.

@github-actions github-actions bot added the cli Tasks related to the Immich CLI label Jul 10, 2025
@Nykri Nykri marked this pull request as ready for review July 22, 2025 13:31
Copy link
Member

@jrasm91 jrasm91 left a comment

Choose a reason for hiding this comment

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

Looks pretty good. There's a bit of cleanup to do, as well as rebasing, but if you are able to do those I think we can merge this in.

Comment on lines +87 to +94
// Merge program options with command options
const mergedOptions = { ...program.opts(), ...options };
upload(paths, program.opts(), mergedOptions);
Copy link
Member

Choose a reason for hiding this comment

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

why are you merging them? they are passed separately to the upload() command and the implementation can handle with merging them if needed, no?

const content = await readFile(this.cacheFile, 'utf-8');
this.cache = JSON.parse(content);
} catch (error) {
console.warn('Failed to load hash cache, starting fresh');
Copy link
Member

Choose a reason for hiding this comment

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

we probably should log the error information as well

async save() {
if (this.isDirty) {
try {
await writeFile(this.cacheFile, JSON.stringify(this.cache, null, 2));
Copy link
Member

Choose a reason for hiding this comment

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

this file is going to be significantly bigger with pretty-print, and it's not meant to be read by humans, so I would probably avoid stringifying it.

Nykri added 2 commits October 12, 2025 18:28
- Implement persistent hash caching to avoid unnecessary file rehashing
- Switch progress bars to show processed file size instead of asset count
- Fix concurrency handling based on CPU count
…m names

Fixes an issue where uploading photos with the same directory name would cause albums to be merged unintentionally. The CLI now properly handles duplicate album names by:
- Generating unique album names when duplicates are detected
- Adding parent directory names to create distinct album name
- Detecting duplicates both on the server and in the current upload batch

This fix is especially useful for directory structure like:
photos/
├── 2023/
│   ├── Bretagne/           -> Album: 2023 Bretagne
│   └── summer/
│       └── beach/          -> Album: 2023 summer beach
│       └── city/           -> Album: 2023 summer city
├── 2024/
│   ├── Bretagne/           -> Album: 2024 Bretagne
│   └── summer/
│       └── beach/          -> Album: 2024 summer beach
│       └── city/           -> Album: 2024 summer city
@Nykri Nykri force-pushed the feat/cli-upload-improvements branch from 1776d96 to 98f261f Compare October 12, 2025 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli Tasks related to the Immich CLI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants