Skip to content

updiff: detect edits from the attach manifest and merge patch chains - #70

Merged
daniel-rossier merged 9 commits into
mainfrom
feat/updiff-attach-baseline
Nov 7, 2026
Merged

daniel-rossier merged 9 commits into
mainfrom
feat/updiff-attach-baseline

Conversation

@daniel-rossier

Copy link
Copy Markdown
Contributor

updiff used to diff the attached tree against ${S}.pristine, so every patched file was a candidate, edited or not. Any difference with the series then counted as an edit: after a git pull bringing new patches, with do_patch not replayed, an updiff about an unrelated file rewrote those patches from the old tree and silently reverted them.

Detection. Candidates now come from the attach manifest: files whose hash changed, files it does not list, files that are gone. Untouched files are not looked at. Without a manifest, the tree is compared to pristine, with a warning, and that old exposure remains. ${S}.pristine stays the base of the replay.

Folding. When an edited file has several patches at the end of the series within one patch set, they become one, and a patch left empty goes away with its .inc line. Patch sets never merge with one another, and a patch with a description, or in a non-generated .inc, is not merged.

Refusals, nothing written:

  • the patches of an edited file changed since the attach;
  • a patch that built the tree left the series and something was edited (an override changed);
  • the tree is attached to another recipe.

Trees shared by two recipes. so3 and usr-so3 both write so3/usr. Their attach traces made updiff so3 refuse an untouched tree, a file folded through one recipe came back as an edit for the other, and with :lvgl updiff so3 took the files usr-so3 attached. A file identical to what the neighbouring recipe attached is now that recipe's.

Also: the :lvgl usr-so3 clean restores the base tree, 0001-CMakeLists.txt.patch of the usr-linux lvgl set is dropped (it repeated the base tree, which made updiff usr-linux fail on an untouched tree), so3 gets its IB_UPDIFF_EXCLUDE, and an append into a patch set no recipe requires now warns.

The result line becomes N unchanged, N rewritten, N merged away, N appended.

Tested

  • full virt64 bsp-linux build from a fresh tree, deploy, QEMU boot to the root shell;
  • U-Boot 2024.07: merges of 2 and 3 patches, deletion, new file, revert to pristine, series moved behind the tree, then a rebuild from the merged patches giving the same tree;
  • so3 and usr-so3 with :lvgl: no false edit, edits folded, refusal when the override is removed;
  • base + bbappend sets on a course tree: the bbappend alone is rewritten.

Not tested

  • linux-6.6-verdin;
  • the :soo override switched for real, only a replay of merged patches with it on;
  • a file edited through so3/usr with updiff usr-so3 alone still lands in the usr-so3 set.

do_diffcompose diffed the tree against ${S}.pristine, so every patched
file came out as a candidate, edited or not, and do_updiff compared it
with the series to sort them out. A file that differs from the series
was then taken for an edit, even when the series had moved: after a
git pull bringing new patches, with do_patch not replayed, an updiff
about an unrelated file rewrote those patches from the old tree and
silently reverted them. A file restored to its pristine state produced
no diff at all, so its patch survived.

Candidates now come from the manifest do_attach_infrabase records:
files whose hash changed, files it does not list, and files that are
gone. Untouched files are not looked at, and the series replay is
checked against the attached hash, so an edit on a file whose patches
moved stops with nothing written. Without a manifest the tree is
compared to pristine, with a warning, and that old exposure remains.
${S}.pristine stays the base of the replay: a hash cannot rebuild the
state the earlier patches leave.

Chains left by the older updiff are merged when such a file is edited:
the tail of the chain lying in one patchset becomes one patch, the
later ones lose their section, and a patch left empty is deleted with
its .inc line. A file back at its state before that tail thus drops
it, which used to be fatal. Patchsets never merge with one another, so
a bbappend stays apart from its base recipe, and a patch with a
description or a non-generated .inc is left alone.

updiff also refuses a tree attached to another recipe. The doc claimed
the diff ran against patched files, which had been wrong for a while.
usr-so3 attaches into so3/usr, and leaves usr.back, usr.attach.sha256 and
the like next to it, inside the so3 tree. updiff of so3 took them for new
files and hit IB_UPDIFF_MAX_NEW on an untouched tree, as soon as a usr.back
existed. These are the build system's own files, in every tree that nests
another, so the class excludes them rather than each recipe.
The series depends on the overrides and the stamps do not, so a tree built
with :lvgl keeps the lvgl changes once the override is removed. Untouched
files are no longer looked at, but an edited one had no chain left: the
whole of what the vanished patch brought was appended with the edit.

do_attach_infrabase now records the series in ${IB_TARGET}.attach.series,
and do_updiff refuses an edit on a tree holding a patch that left it.
Patches added since the attach stay allowed: the replay check already
handles them.
so3/ is gitignored since it is fetched, so the git checkout of the do_clean
restored nothing and the next do_unpack took the lvgl CMakeLists blocks for
pristine. The clean was also skipped once :lvgl was removed, leaving nothing
able to clean such a tree.

Restore from the ${S}/usr of the so3 recipe, which also ships some of the
files the series replaces, and run when the tree was attached with the
series. Any other tree is left alone, as a clean keeps local edits.
so3 and usr-so3 both write so3/usr. With :lvgl, updiff of so3 took the
2000-odd files usr-so3 had attached for its own edits, and a file folded
through one recipe came back as an edit for the other. A file identical
to what the recipe sharing the tree attached is now that recipe's.

An append into a patch set no recipe requires applies nothing, yet was
recorded as part of the series: the next updiff took the tree for one
built with another series and refused. It now warns and records nothing.
The base tree already adds lvgl and graphic: 0001-CMakeLists.txt.patch
added them a second time, which do_configure then removed with a warning.
The tree came out equal to the base, but no longer to its series, so
updiff took the untouched file for an edit undoing the patch and stopped.
IB_SO3_PATH comes from the so3 class, which usr-so3 does not inherit:
every clean of a tree holding the lvgl series died on a TypeError.
A blank line after the comment blocks of these classes, and a short
description for the two functions local to do_updiff.
@daniel-rossier
daniel-rossier merged commit 71efbe4 into main Nov 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant