Skip to content

Add wp media prune command to remove generated thumbnails#239

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/add-media-command-remove-images
Draft

Add wp media prune command to remove generated thumbnails#239
Copilot wants to merge 3 commits intomainfrom
copilot/add-media-command-remove-images

Conversation

Copy link
Contributor

Copilot AI commented Mar 19, 2026

Sites with many registered image sizes accumulate large numbers of generated thumbnails that can be safely deleted and later recreated via wp media regenerate. No built-in WP-CLI command existed to do this selectively and safely.

New command: wp media prune

Deletes generated thumbnail files for registered image sizes and updates attachment metadata accordingly. Abandoned thumbnails (sizes no longer registered) are preserved by default since they cannot be regenerated.

# Remove all generated thumbnails for all images
wp media prune --yes

# Remove only the "large" thumbnails
wp media prune --image_size=large

# Also remove thumbnails for unregistered (abandoned) sizes
wp media prune --remove-abandoned --yes

# Target specific attachments
wp media prune 123 456 789

Options

  • [<attachment-id>...] — limit to specific attachments; omitting prompts for confirmation
  • [--image_size=<size>...] — limit to specific registered sizes (repeatable); validates against registered sizes
  • [--remove-abandoned] — also remove thumbnails whose size is no longer registered
  • [--yes] — bypass confirmation prompt

Key behaviours

  • Never deletes the original full-size file or WP 5.3+ auto-scaled (-scaled) file
  • Abandoned thumbnails (unregistered sizes still in metadata) are kept by default — they may still be linked in content and cannot be regenerated
  • Attachment metadata is updated after deletion so wp media regenerate correctly identifies what needs to be rebuilt
  • Follows the same patterns as regenerate: batch processing, cache clearing every 500 items, report_batch_operation_results() output

Changes

  • src/Media_Command.php — adds prune() public command method and process_prune() private per-attachment helper
  • composer.json — registers media prune as a bundled command
  • features/media-prune.feature — Behat acceptance tests covering: empty set, full prune, size-specific prune, abandoned-size preservation, --remove-abandoned, and invalid size error
Original prompt

This section details on the original issue you should resolve

<issue_title>Media command to remove all generated images</issue_title>
<issue_description>Today I was cleaning up a hosting account for a freelance client by backing up and deleting sites that they no longer use. My typical process for this is to create a zip of the site's final state (including a database export and uploads directory) and tucking it away for safe keeping for a period of time.

One site had a very large uploads directory because of a large number of registered image sizes. This meant a very large ZIP file. However, after removing the generated image sizes leaving only the original, the ZIP file backup was significantly smaller. If I ever need to spin up this site again for whatever reason, I can just restore the database and run wp media regenerate, and all of the image sizes would be present.

I used find . -name "*-*x*.*" | xargs rm -f to accomplish this (props here), but this could remove original files that happen to follow a -400x400. naming pattern. It would be great if there was a command that:

  • Grabbed the list of registered image sizes.
  • Looked at each attachment and removed any generated image that matches a registered image size.
  • Deleted all of these matches from the uploads directory.

Abandoned image sizes (images generated and stored in attachment meta that no longer correspond to a registered image size) would need to remain because those cannot be regenerated, but still may be linked in content.

Almost a reverse regenerate-thumbnails command.</issue_description>

Comments on the Issue (you are @copilot in this section)

@schlessera I think it makes sense to add a command like this.

However, it should be noted that there's no guarantee that if you regenerate the thumbnails, that you'll get the exact same thumbnails with the same settings and the same quality:

  • WordPress can use different image libraries depending on what the server supports. These have differing results.
  • Color correction could be misconfigured on the server, resulting in different colors in the thumbnails.
  • The PHP configuration for the image sizes might have been changed without rebuilding the thumbnails, so some/all of the thumbnails might not actually reflect the current configuration.
  • Plugins (active, inactive or uninstalled ones) might have been used to adapt the thumbnail generation.
  • The plugins might have been generated via an external service which might or might not be available from the target location.

This is a destructive operation, and although there is a good probability that regeneration will recreate what was deleted, there's no guarantee for that.</comment_new>
<comment_new>@schlessera
Analogous to regenerate, this could be called prune.

It could have an optional flag --remove-abandoned to get rid of thumbnails that can't be regenerated anymore.</comment_new>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@github-actions github-actions bot added command:media Related to 'media' command command:media-regenerate Related to 'media regenerate' command scope:distribution Related to distribution status:unconfirmed Issue was could not be confirmed yet labels Mar 19, 2026
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Copilot AI changed the title [WIP] Add media command to remove all generated images Add wp media prune command to remove generated thumbnails Mar 19, 2026
Copilot AI requested a review from swissspidy March 19, 2026 23:01
@codecov
Copy link

codecov bot commented Mar 19, 2026

Codecov Report

❌ Patch coverage is 76.66667% with 21 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Media_Command.php 76.66% 21 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new wp media prune subcommand to the media-command package to safely delete generated attachment thumbnails (optionally limited to specific registered sizes and/or including abandoned sizes) while updating attachment metadata so thumbnails can later be recreated via wp media regenerate.

Changes:

  • Add Media_Command::prune() command and process_prune() helper to remove intermediate image files and update attachment metadata.
  • Register the new media prune command as bundled in composer.json.
  • Add Behat acceptance coverage for pruning behavior (all images, specific sizes, abandoned-size handling, and invalid size errors).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/Media_Command.php Implements the new wp media prune command and per-attachment pruning logic.
features/media-prune.feature Adds acceptance tests for prune scenarios and option behaviors.
composer.json Registers media prune as a bundled WP-CLI command.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1063 to +1068
if ( file_exists( $intermediate_path ) ) {
unlink( $intermediate_path );
}

$sizes_to_prune[] = $size_name;
}
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

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

The code unconditionally adds a size to $sizes_to_prune and unsets its metadata even if unlink() fails (and unlink() failures can also emit PHP warnings). Consider checking the return value of unlink() (and handling missing/undeletable files separately) so metadata is only removed when the file is successfully deleted (or already absent), and increment $errors / log a warning when deletion fails.

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

command:media Related to 'media' command command:media-regenerate Related to 'media regenerate' command scope:distribution Related to distribution status:unconfirmed Issue was could not be confirmed yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Media command to remove all generated images

3 participants