Development
Move iCloud Photos and Videos to Google Photos from Linux

Apple offers a direct transfer of a copy of iCloud Photos to Google Photos. Try that first if you want a whole-library copy and your account is eligible. It leaves the iCloud originals in place, but Apple says Live Photos, some metadata, and certain albums or formats may not transfer. For a selected collection, separate photo and video handling, or an independent local backup, a Linux workstation gives you more control.
The workflow below copies with icloudpd, checks the files locally, then uploads them through Google Photos. It does not delete from iCloud. Allow enough disk space for the downloads and a second backup, plus enough Google account storage for the upload.
Download photos and videos into separate folders
Install a current icloudpd release using the project's installation instructions. Check icloudpd --version and icloudpd --help because flags vary across releases. Its reference documents --skip-videos and --skip-photos; version 1.30.0 added the latter. Authenticate interactively with two-factor authentication. Avoid putting your Apple Account password on a command line or in a shell alias, history file, script, or screenshot.
These are safe, reusable equivalents of separate photo and video download aliases. Set ICLOUD_USER locally to your own Apple Account address; do not paste the value into a public log. Choose a private destination with adequate space. The example uses --size original and omits all deletion flags.
icloud_photos() {
icloudpd --username "$ICLOUD_USER" --directory "$HOME/iCloud-export/photos" --size original --skip-videos "$@"
}
icloud_videos() {
icloudpd --username "$ICLOUD_USER" --directory "$HOME/iCloud-export/videos" --size original --skip-photos "$@"
}
icloud_photos --dry-run
icloud_videos --dry-run
icloud_photos
icloud_videos
The project's multiple-config example uses the same separate-folder filters. A Live Photo contains a still and a motion component; keep both when archiving and check the resulting filenames. An export into separate folders may put the still and companion video in different places, so do not assume a photo count and a video count map one-to-one to iCloud items. Preserve the originals even if you later make converted copies.
For a partial migration, add a real, checked date such as --skip-created-before 2024-01-01 to each dry run before downloading. This means skip assets created before that date, based on the photo's creation date rather than its iCloud upload date. Confirm the intended boundary and timezone with sample items. A bare --skip-created-before has no value and is not a working alias; a guessed date can silently omit wanted memories. The flag reference also documents relative values, but an explicit ISO date is easier to audit for a one-time migration.
Verify locally before uploading
Record how many files landed in each folder and their total sizes. For example:
find "$HOME/iCloud-export/photos" -type f | wc -l
find "$HOME/iCloud-export/videos" -type f | wc -l
du -sh "$HOME/iCloud-export/photos" "$HOME/iCloud-export/videos"
find "$HOME/iCloud-export/photos" "$HOME/iCloud-export/videos" -type f -size 0 -print
Review files from the oldest and newest dates, plus a few from each year or album. Open representative HEIC images and MOV/MP4 videos, check that they are full size and playable, inspect capture dates and location metadata where expected, and compare them with the same items in iCloud Photos. File modification time alone is not proof of capture date. If you need an exact set, make a manifest of filenames, sizes, and checksums, and reconcile it against the chosen iCloud selection. Counts can differ because Live Photos and RAW+JPEG pairs produce multiple files, while duplicate naming and filters affect output. Resolve any gap before treating the export as complete.
Copy the verified folder tree to a separate disk and check several files from that backup. icloudpd --delete-after-download is a destructive iCloud operation: the tool's reference says it moves newly downloaded assets into Recently Deleted and marks the flag deprecated. Do not add it to migration aliases. A local copy or a Google upload in progress is not a reason to remove iCloud originals. The separate --auto-delete flag can delete local files that disappear in iCloud, so leave that off an archival export too.
Upload to Google Photos
Open photos.google.com on Linux in the intended Google Account. Start with a small, representative batch using Create > Import photos or drag files into an album, then inspect the results before importing the rest. Google's computer upload instructions list HEIC/HEIF photos and MOV/MP4 videos among supported types, with file size limits. HEVC is a video codec often inside MOV or MP4, so test a representative clip for playback; a supported extension does not guarantee every codec variant will work. If a file fails, keep the original and convert a copy to a supported format.
A Linux file upload of a Live Photo's still and motion file is not guaranteed to reconstruct one interactive Live Photo. Google documents Live Photo backup through its iPhone or iPad app; use that route if preserving the motion effect in Google Photos matters, and check the result before removing anything. Keep original still and motion files in the local archive either way.
Google Photos does not recreate the iCloud folder and album structure merely because files came from named local directories. Create destination albums intentionally, upload or add the matching files, and spot-check membership. Compare capture dates, location, captions, edits, and representative RAW or portrait images. Metadata in sidecars may need separate handling; do not assume every iCloud detail becomes a Google Photos field. Uploading again or mixing this route with Apple's direct transfer can create duplicate-looking items, so use one tracked batch at a time and inspect what is already there before retrying.
Confirm the transfer and retain a way back
After each batch, check upload completion and inspect samples at the beginning, middle, and end of the date range in Google Photos. Compare photo and video counts with your local manifest, allowing for Live Photo pairs and rejected or duplicate files; verify full-resolution viewing, video playback, dates, metadata, and albums. Keep a written list of failed files and retry them individually. Make sure the destination Google Account and storage usage are what you expected.
Retain the verified local backup and iCloud library while you use Google Photos for a while. If the upload is incomplete or metadata is wrong, stop further batches and retry from the original local files or iCloud rather than overwriting the only copy. Only consider removing iCloud content after independent backups and the destination have been checked. Apple's direct transfer, if used instead, also keeps iCloud content and has its own format and album limits; review its completion notice and samples in Google Photos.