What an edited copy looks like next to its original
| Edited copy | JSON it shares | Reported in |
|---|---|---|
IMG_20140515_063415-edited.jpg | IMG_20140515_063415.jpg.supplemental-metadata.json | immich-go issue #673 |
IMAG0061-edited.JPG | IMAG0061.JPG.supplemental-metadata.json | immich-go test suite |
PXL_20220405_090123740.PORTRAIT-modifié.jpg | PXL_20220405_090123740.PORTRAIT.jpg.json | immich-go test suite (French account, old format) |
simple_file_20200101-edited(1).jpg | simple_file_20200101.jpg.json | GooglePhotosTakeoutHelper test suite |
The immich-go documentation states the general case: edited images "may not have corresponding JSON". The fourth row combines two rules, an edit suffix and a duplicate number; the original GooglePhotosTakeoutHelper only finds that pairing in its slower "tryhard" pass.
Examples from immich-go #673, immich-go matcher_test.go and GPTH gpth_test.dart.
The suffix depends on your account's language
The three projects keep their own lists, built from user reports. GooglePhotosTakeoutHelper knows -edited, -effects, -smile, -mix, -edytowane, -bearbeitet, -bewerkt, -編集済み, -modificato, -modifié, -ha editado and -editat. GPTH_Neo adds -motion, -animation, -collage, -编辑, -editada and -editado, compares case-insensitively after Unicode normalization, and also strips a suffix that Google cut short, such as -ed, when it is at least two characters. immich-go keeps no list at all: its edited-name rule is a plain prefix match, and its documentation names -editado, -отредактировано, -编辑, -編集済み, -편집됨, -bewerkt, -muokattu, -відредаговано, -edytowane, -redigeret and -upravené as reported, with only -modifié, -bearbeitet and -modificato marked as confirmed.
FixMyTakeout's list is the union of all of these: -edited, -effects, -smile, -mix, -motion, -animation, -collage, -bearbeitet, -bewerkt, -modifié, -modificato, -editado, -editada, -ha editado, -editat, -edytowane, -redigeret, -muokattu, -upravené, -отредактировано, -відредаговано, -編集済み, -编辑 and -편집됨, matched without regard to case and after normalizing accented characters. A suffix that Google truncated to a fragment is not on the list, so a file like photo-ed.jpg would keep its own embedded date instead.
The importers disagree about what the copy inherits
All three find the original's JSON. What they do with it differs:
| Tool | Date | Location | Caption |
|---|---|---|---|
| immich-go | From the original's JSON | From the original's JSON | From the original's JSON |
| GooglePhotosTakeoutHelper | From the original's JSON | Not written (no GPS support) | Not written |
| GPTH_Neo since 6.1.10 | Refused; falls back to EXIF, file name, then folder year | Refused | Refused |
GPTH_Neo's refusal came from issue #139 in August 2026, where 34.5 percent of the outputs that received GPS had been given another photo's coordinates by heuristic matches. The fix marks any JSON found through a guess as not the file's own and takes nothing from it. That is a sound response to fuzzy matching. It also means every edited copy in a GPTH_Neo run loses Google's date and place unless the copy happens to carry EXIF of its own.
Behavior from GPTH_Neo's CHANGELOG.md and issue #139; immich-go's matchers.go.
Why FixMyTakeout gives the edited copy the original's data
The edited copy is the same photo. It was taken at the same moment in the same place, and the caption you wrote applies to it. What made inheritance dangerous in the #139 case was the matching, not the inheriting: heuristic matches attached the wrong JSON, and once the wrong JSON is attached, every field it contributes is wrong. A prefix match with no boundary, for example, would let IMG_1234.HEIC.json claim IMG_12345.MOV.
FixMyTakeout matches an edited copy by its exact derived name. It removes a suffix from the list above, rebuilds the original's name with the extension, and looks for precisely the JSON names Google would have written for that original: the supplemental form, the classic form, and any shortened suffix, each with the copy's duplicate number when it has one. Nothing shorter than the whole original name is accepted. When that lookup succeeds, the copy is treated as owning the JSON: it gets the original's date, its location when the copy has none, and its caption. The report marks these rows edited copy of the original in the matched_by column.
Two details worth knowing. With the default date rule, an edited copy that already carries a camera date agreeing with Google's (apart from time zone) keeps that date unchanged. And if a copy's suffix was cut to a fragment by the 51-character rule, no match is attempted and the copy keeps whatever date it has inside.
Check the edited copies in your export
- Search the export for
-edited(or your language's suffix). Most hits will have no JSON beside them. - After a run, filter
fixmytakeout-report.csvonmatched_byforedited copy of the original. Thesidecarcolumn names the original's JSON that was used. - Open one original and its edited copy in your photo app. Both should now sit on the same day, in the same place.