ENH: Ingest ITKGenericLabelInterpolator into Modules/Filtering#6135
Conversation
|
| Filename | Overview |
|---|---|
| Modules/Filtering/GenericLabelInterpolator/include/itkLabelImageGenericInterpolateImageFunction.h | Main class header: correctly delegates GetRadius() to internal interpolators (fixing the previous P1), proper Doxygen groups, standard ITK type-alias boilerplate. |
| Modules/Filtering/GenericLabelInterpolator/include/itkLabelImageGenericInterpolateImageFunction.hxx | Implementation: SetInputImage scans labels, builds per-label adaptors/interpolators; EvaluateAtContinuousIndex returns label with highest interpolated weight. Contains const_cast (P2, acknowledged in comment). |
| Modules/Filtering/GenericLabelInterpolator/itk-module.cmake | Module descriptor with correct DEPENDS (ITKSmoothing, ITKImageAdaptors, ITKImageFunction explicit), TEST_DEPENDS, EXCLUDE_FROM_DEFAULT, ENABLE_SHARED — addresses previous ITKImageFunction dependency finding. |
| Modules/Filtering/GenericLabelInterpolator/test/CMakeLists.txt | Test driver setup and single itk_add_test; trailing slash on output dir arg leads to double slash in written path (P2); only one of seven interpolator outputs is baseline-compared. |
| Modules/Filtering/GenericLabelInterpolator/test/RotateLabels.cxx | Rotation torture test for seven interpolator variants; only the Gaussian-with-3-rotations output is validated against a baseline. Core test logic is correct. |
| Modules/Filtering/GenericLabelInterpolator/wrapping/itkLabelImageGenericInterpolateImageFunction.wrap | Wraps Linear and NearestNeighbor variants for all scalar+UC+colour types; vector types intentionally commented out due to upstream operator< limitation. |
| Modules/Remote/GenericLabelInterpolator.remote.cmake | Remote module descriptor correctly removed now that the module is in-tree. |
| pyproject.toml | Adds -DModule_GenericLabelInterpolator:BOOL=ON to the CI configure command, consistent with AnisotropicDiffusionLBR and Montage entries. |
Class Diagram
%%{init: {'theme': 'neutral'}}%%
classDiagram
class InterpolateImageFunction {
+EvaluateAtContinuousIndex()
+GetRadius() SizeType
+SetInputImage()
}
class LabelImageGenericInterpolateImageFunction {
-m_Labels : LabelSetType
-m_InternalInterpolators : vector
-m_LabelSelectionAdaptors : vector
+SetInputImage(image)
+EvaluateAtContinuousIndex(cindex) OutputType
+GetRadius() SizeType
}
class LabelSelectionImageAdaptor {
+SetAcceptedValue(value)
}
class ImageAdaptor {
+SetImage(image)
}
class LabelSelectionPixelAccessor {
-m_AcceptedValue : TInternalType
+Get(input) TExternalType
+SetAcceptedValue(value)
}
class TInterpolator {
<<template>>
+EvaluateAtContinuousIndex()
+GetRadius() SizeType
+SetInputImage()
}
InterpolateImageFunction <|-- LabelImageGenericInterpolateImageFunction
ImageAdaptor <|-- LabelSelectionImageAdaptor
LabelSelectionImageAdaptor --> LabelSelectionPixelAccessor : uses accessor
LabelImageGenericInterpolateImageFunction --> LabelSelectionImageAdaptor : 1 per label
LabelImageGenericInterpolateImageFunction --> TInterpolator : 1 per label
TInterpolator --> LabelSelectionImageAdaptor : SetInputImage(adaptor)
Reviews (2): Last reviewed commit: "BUG: Delegate GetRadius() to the wrapped..." | Re-trigger Greptile
ee16b27 to
e6e4dc0
Compare
|
@greptileai review Re-review on new HEAD |
a66a0ad to
eeb4293
Compare
|
@dzenanz The ghostflow issues would require changing the commit history. I chose not to do that for the ingestions. |
|
@hjmjohnson I don't think it's worth changing the commit messages. But I do see there are some white space issues in the history. Extra white space and EOF not where expected. Do the current file pass these white space tests? It may be reasonable to automate a fix up the commit history for these whitespace errors. |
|
We can ignore ghostflow in this case. Brad's idea to remove trailing whitespaces sounds good to me. |
|
@dzenanz @blowekamp, cleaning up the whitespace and cleaning up the commit messages are both really easy and quite safe to do. As I move forward with ingesting other remote modules, it is a really easy thing to add, and it will make reviewing the PR's easier. The reason I didn't do that was to preserve the original code, but now that I think about it, I think the benefits of byte-for-byte preservation are probably a vanishingly small benefit. |
|
Did the trailing whitespaces get removed by the merge commit (1ee0cb1)? That is fine, too. |
eeb4293 to
fc200e3
Compare
Adds Utilities/Maintenance/RemoteModuleIngest/normalize-ingest-commits.py and documents it in INGESTION_STRATEGY.md as a mandatory pass for modes A (full-history) and B (filtered-history). For each commit in <base>..HEAD the driver: - cherry-picks with -X theirs so an earlier commit's pre-commit auto-fix never blocks a later commit's content from replaying; - runs pre-commit on the touched paths and re-stages auto-fixes (whitespace, EOF, gersemi, clang-format); - normalizes the subject line to ITK conventions (BUG:/COMP:/DOC:/ ENH:/PERF:/STYLE: prefix, <= 78 chars), preserving the original subject as "Original subject: <text>" in the body when rewriting; - drops commits that become empty after pre-commit -- intermediate style-only commits that today's hooks would have prevented; - preserves GIT_AUTHOR_NAME / GIT_AUTHOR_EMAIL / GIT_AUTHOR_DATE verbatim. Only committer + committer date change. The script is idempotent. The tip tree is byte-identical before and after the normalization, so CI behavior is unchanged; only intra-history trees become clean. Addresses feedback on PR InsightSoftwareConsortium#6135 from @blowekamp ("white space issues in the history") and @dzenanz ("Brad's idea to remove trailing whitespaces sounds good to me") and forms the new default for remote-module ingests. Assisted-by: Claude Code (claude-opus-4-7) -- script implementation and INGESTION_STRATEGY.md update
fc200e3 to
4db9b1e
Compare
|
@blowekamp @dzenanz — applied the per-commit cleanup we discussed. Summary on new HEAD
The driver landed as a new commit at the tip ( Verification commands# Tip tree unchanged
git diff pre-normalize-6135..HEAD # empty
# Authorship preserved (compare against the pre-rewrite branch)
git log --format='%an <%ae>' upstream/main..HEAD | sort -u # 12 distinct authors
# Every historical commit passes modern pre-commit
for sha in $(git rev-list upstream/main..HEAD); do
git stash && git checkout $sha
pre-commit run --files Modules/Filtering/GenericLabelInterpolator/**/* \
|| echo "DIRTY: $sha"
git checkout - && git stash pop
done # no DIRTY lines |
Adds Utilities/Maintenance/RemoteModuleIngest/normalize-ingest-commits.py and documents it in INGESTION_STRATEGY.md as a mandatory pass for modes A (full-history) and B (filtered-history). For each commit in <base>..HEAD the driver: - cherry-picks with -X theirs so an earlier commit's pre-commit auto-fix never blocks a later commit's content from replaying; - runs pre-commit on the touched paths and re-stages auto-fixes (whitespace, EOF, gersemi, clang-format); - normalizes the subject line to ITK conventions (BUG:/COMP:/DOC:/ ENH:/PERF:/STYLE: prefix, <= 78 chars), preserving the original subject as "Original subject: <text>" in the body when rewriting; - drops commits that become empty after pre-commit -- intermediate style-only commits that today's hooks would have prevented; - preserves GIT_AUTHOR_NAME / GIT_AUTHOR_EMAIL / GIT_AUTHOR_DATE verbatim. Only committer + committer date change. The script is idempotent. The tip tree is byte-identical before and after the normalization, so CI behavior is unchanged; only intra-history trees become clean. Addresses feedback on PR InsightSoftwareConsortium#6135 from @blowekamp ("white space issues in the history") and @dzenanz ("Brad's idea to remove trailing whitespaces sounds good to me") and forms the new default for remote-module ingests. Assisted-by: Claude Code (claude-opus-4-7) -- script implementation and INGESTION_STRATEGY.md update
4db9b1e to
68a9eb3
Compare
|
@blowekamp @dzenanz — followup on |
|
I just took a look. All the commit now live on top of the main branch. Which is different from the other ingested modules, and feels strange. I assume it would be confusing to someone in the future reading the log, unaware of this recent ingestion campaign. |
Adds Utilities/Maintenance/RemoteModuleIngest/normalize-ingest-commits.py and documents it in INGESTION_STRATEGY.md as a mandatory pass for modes A (full-history) and B (filtered-history). For each commit in <base>..HEAD the driver: - cherry-picks with -X theirs so an earlier commit's pre-commit auto-fix never blocks a later commit's content from replaying; - runs pre-commit on the touched paths and re-stages auto-fixes (whitespace, EOF, gersemi, clang-format); - normalizes the subject line to ITK conventions (BUG:/COMP:/DOC:/ ENH:/PERF:/STYLE: prefix, <= 78 chars), preserving the original subject as "Original subject: <text>" in the body when rewriting; - drops commits that become empty after pre-commit -- intermediate style-only commits that today's hooks would have prevented; - preserves GIT_AUTHOR_NAME / GIT_AUTHOR_EMAIL / GIT_AUTHOR_DATE verbatim. Only committer + committer date change. The script is idempotent. The tip tree is byte-identical before and after the normalization, so CI behavior is unchanged; only intra-history trees become clean. Addresses feedback on PR InsightSoftwareConsortium#6135 from @blowekamp ("white space issues in the history") and @dzenanz ("Brad's idea to remove trailing whitespaces sounds good to me") and forms the new default for remote-module ingests. Assisted-by: Claude Code (claude-opus-4-7) -- script implementation and INGESTION_STRATEGY.md update
Adds a "The root-commit ghostflow error is REQUIRED, not a failure"
subsection to INGESTION_STRATEGY.md.
The orphan root commit on the side branch is the structural
signature of an unrelated-history merge -- git merge
--allow-unrelated-histories --no-ff requires that the second
parent of the merge commit have no common ancestor with main,
which forces the side branch's first commit to be a root commit.
Ghostflow's "no root commits" rule is a sensible default for
normal contributions but is structurally incompatible with
remote-module ingestion.
Ingest acceptance criteria, in priority order:
1. Exactly one ghostflow error
2. The error is the "root commit not allowed" form
3. The flagged SHA equals the side branch's tail commit
Any of these are real failures that must be fixed:
- More than one ghostflow error
- A root-commit error pointing at any commit not on the
side branch
- Trailing-whitespace or missing-newline errors
For PR InsightSoftwareConsortium#6135 (and future ingests), reviewers should treat the
single "root commit" error as green -- it confirms the merge
topology was built correctly. Insisting on a fully-green
ghostflow would force re-flattening to a linear rebase, which
destroys the merge join and blame walk that the merge-topology
requirement was added to preserve.
|
For reviewers: ghostflow on this PR shows exactly one error and that is intentional and required: This is the structural signature of the unrelated-history merge — Codified in
Anything beyond that single root-commit error (e.g., trailing-whitespace or missing-EOF errors) is a real failure that must be fixed before merge — those would indicate either intermediate-commit drift or a side-branch tree that wasn't subtree-only.
|
d1eab72
into
InsightSoftwareConsortium:main
…is repo The GenericLabelInterpolator module was ingested into the main ITK source tree on 2026-04-27 via InsightSoftwareConsortium/ITK#6135 (merge commit d1eab72aa6315d66cbe535a7ca61cf3c4ef60ffa). Per the ITK ingestion strategy (Utilities/Maintenance/RemoteModuleIngest/INGESTION_STRATEGY.md), the one-definition rule requires that any file now living at Modules/Filtering/GenericLabelInterpolator/ in ITK no longer live at this upstream repo's tree tip. This commit: - Removes the whitelisted files that transferred during ingest: include/, test/, wrapping/, CMakeLists.txt, itk-module.cmake, CTestConfig.cmake. - Adds MIGRATION_README.md at the repo root pointing users at the authoritative in-tree ITK location and linking the ingest PR. - Leaves the pre-ingest history intact so blame, paper material, the document/ tree, README.rst, LICENSE, and any other deliberately-not-migrated artifacts remain reachable. After this PR merges, this repository will be marked ARCHIVED via GitHub's repository settings (Danger Zone -> Archive this repository), making it read-only. Cloning ITK main gets the authoritative module under Modules/Filtering/GenericLabelInterpolator/. Cloning this repo after archival gets only the MIGRATION_README pointer plus everything that was deliberately not migrated.
The upstream remote module's top-level CMakeLists.txt carried a dual-mode preamble that supports both standalone (find_package(ITK) + ITKModuleExternal) and in-tree (itk_module_impl) builds. Once the module lives under Modules/Filtering/, only the in-tree branch is reachable -- the standalone branch is dead code, the cmake_minimum_required and project() lines duplicate what ITK's root CMake already owns. Collapse the file to a single itk_module_impl() call, matching every other in-tree Modules/<Group>/<Name>/ module. Per the standalone-build cleanup convention documented in Utilities/Maintenance/RemoteModuleIngest/INGESTION_STRATEGY.md under "Standalone-build boilerplate cleanup (modes A/B)" and applied previously to GenericLabelInterpolator (PR InsightSoftwareConsortium#6135) and MGHIO (PR InsightSoftwareConsortium#6137).
The module now lives at Modules/Filtering/FastBilateral/. The configure-time fetch declaration in Modules/Remote/ would otherwise clone the (soon-to-be-archived) upstream and double-define the module. Mirrors the in-tree transition completed for GenericLabelInterpolator (PR InsightSoftwareConsortium#6135) and MGHIO (PR InsightSoftwareConsortium#6137).
The upstream remote module's top-level CMakeLists.txt carried a dual-mode preamble that supports both standalone (find_package(ITK) + ITKModuleExternal) and in-tree (itk_module_impl) builds. Once the module lives under Modules/Filtering/, only the in-tree branch is reachable -- the standalone branch is dead code, the cmake_minimum_required and project() lines duplicate what ITK's root CMake already owns. Collapse the file to a single itk_module_impl() call, matching every other in-tree Modules/<Group>/<Name>/ module. Per the standalone-build cleanup convention documented in Utilities/Maintenance/RemoteModuleIngest/INGESTION_STRATEGY.md under "Standalone-build boilerplate cleanup (modes A/B)" and applied previously to GenericLabelInterpolator (PR InsightSoftwareConsortium#6135) and MGHIO (PR InsightSoftwareConsortium#6137).
The module now lives at Modules/Filtering/FastBilateral/. The configure-time fetch declaration in Modules/Remote/ would otherwise clone the (soon-to-be-archived) upstream and double-define the module. Mirrors the in-tree transition completed for GenericLabelInterpolator (PR InsightSoftwareConsortium#6135) and MGHIO (PR InsightSoftwareConsortium#6137).
The upstream remote module's top-level CMakeLists.txt carried a dual-mode preamble that supports both standalone (find_package(ITK) + ITKModuleExternal) and in-tree (itk_module_impl) builds. Once the module lives under Modules/Filtering/, only the in-tree branch is reachable -- the standalone branch is dead code, the cmake_minimum_required and project() lines duplicate what ITK's root CMake already owns. Collapse the file to a single itk_module_impl() call, matching every other in-tree Modules/<Group>/<Name>/ module. Per the standalone-build cleanup convention documented in Utilities/Maintenance/RemoteModuleIngest/INGESTION_STRATEGY.md under "Standalone-build boilerplate cleanup (modes A/B)" and applied previously to GenericLabelInterpolator (PR InsightSoftwareConsortium#6135) and MGHIO (PR InsightSoftwareConsortium#6137).
The module now lives at Modules/Filtering/FastBilateral/. The configure-time fetch declaration in Modules/Remote/ would otherwise clone the (soon-to-be-archived) upstream and double-define the module. Mirrors the in-tree transition completed for GenericLabelInterpolator (PR InsightSoftwareConsortium#6135) and MGHIO (PR InsightSoftwareConsortium#6137).
The normalize-ingest-commits.py script replays each non-merge upstream commit via cherry-pick and skips merges entirely. The result loses the upstream merge topology, which the strategy doc has always mandated as preserved. Reviewers flagged this on PRs InsightSoftwareConsortium#6135, InsightSoftwareConsortium#6137, InsightSoftwareConsortium#6159, and InsightSoftwareConsortium#6161 before it became a rule violation. This commit: 1. Adds a hard refuse-to-run guard to normalize-ingest-commits.py (exit 3 with deprecation notice unless --i-understand-this-linearizes is passed). The guard names the replacement and points at the strategy doc. 2. Adds rewrite-history-merge-preserving.py — a git-filter-repo driven rewriter that walks every commit (merges included) and applies uniform text-blob normalization (trailing-whitespace strip + EOF-newline fix). Implements the user-mandated Phase 1 reference / Phase 2 traversal / Phase 3 verification architecture. 3. Updates INGESTION_STRATEGY.md with the "Linearization is forbidden" subsection, an allowed-tool table for per-commit re-formatting, and the new operator check that the merge count satisfies 1 + UPSTREAM_INTERNAL_MERGES. Language-specific formatters (clang-format, gersemi) are intentionally NOT applied per blob — they require the destination's current config, and applying them retroactively across upstream history would produce spurious diffs. The recommended pattern is a single "STYLE: Apply current formatters" commit at the rewritten tip after Phase 2 succeeds.
The normalize-ingest-commits.py script replays each non-merge upstream commit via cherry-pick and skips merges entirely. The result loses the upstream merge topology, which the strategy doc has always mandated as preserved. Reviewers flagged this on PRs InsightSoftwareConsortium#6135, InsightSoftwareConsortium#6137, InsightSoftwareConsortium#6159, and InsightSoftwareConsortium#6161 before it became a rule violation. This commit: 1. Adds a hard refuse-to-run guard to normalize-ingest-commits.py (exit 3 with deprecation notice unless --i-understand-this-linearizes is passed). The guard names the replacement and points at the strategy doc. 2. Adds rewrite-history-merge-preserving.py — a git-filter-repo driven rewriter that walks every commit (merges included) and applies uniform text-blob normalization (trailing-whitespace strip + EOF-newline fix). Implements the user-mandated Phase 1 reference / Phase 2 traversal / Phase 3 verification architecture. 3. Updates INGESTION_STRATEGY.md with the "Linearization is forbidden" subsection, an allowed-tool table for per-commit re-formatting, and the new operator check that the merge count satisfies 1 + UPSTREAM_INTERNAL_MERGES. Language-specific formatters (clang-format, gersemi) are intentionally NOT applied per blob — they require the destination's current config, and applying them retroactively across upstream history would produce spurious diffs. The recommended pattern is a single "STYLE: Apply current formatters" commit at the rewritten tip after Phase 2 succeeds.
The normalize-ingest-commits.py script replays each non-merge upstream commit via cherry-pick and skips merges entirely. The result loses the upstream merge topology, which the strategy doc has always mandated as preserved. Reviewers flagged this on PRs InsightSoftwareConsortium#6135, InsightSoftwareConsortium#6137, InsightSoftwareConsortium#6159, and InsightSoftwareConsortium#6161 before it became a rule violation. This commit: 1. Adds a hard refuse-to-run guard to normalize-ingest-commits.py (exit 3 with deprecation notice unless --i-understand-this-linearizes is passed). The guard names the replacement and points at the strategy doc. 2. Adds rewrite-history-merge-preserving.py — a git-filter-repo driven rewriter that walks every commit (merges included) and applies uniform text-blob normalization (trailing-whitespace strip + EOF-newline fix). Implements the user-mandated Phase 1 reference / Phase 2 traversal / Phase 3 verification architecture. 3. Updates INGESTION_STRATEGY.md with the "Linearization is forbidden" subsection, an allowed-tool table for per-commit re-formatting, and the new operator check that the merge count satisfies 1 + UPSTREAM_INTERNAL_MERGES. Language-specific formatters (clang-format, gersemi) are intentionally NOT applied per blob — they require the destination's current config, and applying them retroactively across upstream history would produce spurious diffs. The recommended pattern is a single "STYLE: Apply current formatters" commit at the rewritten tip after Phase 2 succeeds.
The normalize-ingest-commits.py script replays each non-merge upstream commit via cherry-pick and skips merges entirely. The result loses the upstream merge topology, which the strategy doc has always mandated as preserved. Reviewers flagged this on PRs InsightSoftwareConsortium#6135, InsightSoftwareConsortium#6137, InsightSoftwareConsortium#6159, and InsightSoftwareConsortium#6161 before it became a rule violation. This commit: 1. Adds a hard refuse-to-run guard to normalize-ingest-commits.py (exit 3 with deprecation notice unless --i-understand-this-linearizes is passed). The guard names the replacement and points at the strategy doc. 2. Adds rewrite-history-merge-preserving.py — a git-filter-repo driven rewriter that walks every commit (merges included) and applies uniform text-blob normalization (trailing-whitespace strip + EOF-newline fix). Implements the user-mandated Phase 1 reference / Phase 2 traversal / Phase 3 verification architecture. 3. Updates INGESTION_STRATEGY.md with the "Linearization is forbidden" subsection, an allowed-tool table for per-commit re-formatting, and the new operator check that the merge count satisfies 1 + UPSTREAM_INTERNAL_MERGES. Language-specific formatters (clang-format, gersemi) are intentionally NOT applied per blob — they require the destination's current config, and applying them retroactively across upstream history would produce spurious diffs. The recommended pattern is a single "STYLE: Apply current formatters" commit at the rewritten tip after Phase 2 succeeds.
The normalize-ingest-commits.py script replays each non-merge upstream commit via cherry-pick and skips merges entirely. The result loses the upstream merge topology, which the strategy doc has always mandated as preserved. Reviewers flagged this on PRs InsightSoftwareConsortium#6135, InsightSoftwareConsortium#6137, InsightSoftwareConsortium#6159, and InsightSoftwareConsortium#6161 before it became a rule violation. This commit: 1. Adds a hard refuse-to-run guard to normalize-ingest-commits.py (exit 3 with deprecation notice unless --i-understand-this-linearizes is passed). The guard names the replacement and points at the strategy doc. 2. Adds rewrite-history-merge-preserving.py — a git-filter-repo driven rewriter that walks every commit (merges included) and applies uniform text-blob normalization (trailing-whitespace strip + EOF-newline fix). Implements the user-mandated Phase 1 reference / Phase 2 traversal / Phase 3 verification architecture. 3. Updates INGESTION_STRATEGY.md with the "Linearization is forbidden" subsection, an allowed-tool table for per-commit re-formatting, and the new operator check that the merge count satisfies 1 + UPSTREAM_INTERNAL_MERGES. Language-specific formatters (clang-format, gersemi) are intentionally NOT applied per blob — they require the destination's current config, and applying them retroactively across upstream history would produce spurious diffs. The recommended pattern is a single "STYLE: Apply current formatters" commit at the rewritten tip after Phase 2 succeeds.
Adds Utilities/Maintenance/RemoteModuleIngest/normalize-ingest-commits.py and documents it in INGESTION_STRATEGY.md as a mandatory pass for modes A (full-history) and B (filtered-history). For each commit in <base>..HEAD the driver: - cherry-picks with -X theirs so an earlier commit's pre-commit auto-fix never blocks a later commit's content from replaying; - runs pre-commit on the touched paths and re-stages auto-fixes (whitespace, EOF, gersemi, clang-format); - normalizes the subject line to ITK conventions (BUG:/COMP:/DOC:/ ENH:/PERF:/STYLE: prefix, <= 78 chars), preserving the original subject as "Original subject: <text>" in the body when rewriting; - drops commits that become empty after pre-commit -- intermediate style-only commits that today's hooks would have prevented; - preserves GIT_AUTHOR_NAME / GIT_AUTHOR_EMAIL / GIT_AUTHOR_DATE verbatim. Only committer + committer date change. The script is idempotent. The tip tree is byte-identical before and after the normalization, so CI behavior is unchanged; only intra-history trees become clean. Addresses feedback on PR InsightSoftwareConsortium#6135 from @blowekamp ("white space issues in the history") and @dzenanz ("Brad's idea to remove trailing whitespaces sounds good to me") and forms the new default for remote-module ingests. Assisted-by: Claude Code (claude-opus-4-7) -- script implementation and INGESTION_STRATEGY.md update
Adds a "Post-merge fixup hazard" subsection to INGESTION_STRATEGY.md warning that plain `git rebase --autosquash upstream/main` after the ingest merge silently re-flattens the merge topology. Records the second linear-history regression on PR InsightSoftwareConsortium#6135 (4bc617fb38 → a8f3bc1) as the cautionary tale and prescribes either discrete on-top commits or `git rebase --rebase-merges --autosquash <merge>^` as the safe alternatives.
Adds a "The root-commit ghostflow error is REQUIRED, not a failure"
subsection to INGESTION_STRATEGY.md.
The orphan root commit on the side branch is the structural
signature of an unrelated-history merge -- git merge
--allow-unrelated-histories --no-ff requires that the second
parent of the merge commit have no common ancestor with main,
which forces the side branch's first commit to be a root commit.
Ghostflow's "no root commits" rule is a sensible default for
normal contributions but is structurally incompatible with
remote-module ingestion.
Ingest acceptance criteria, in priority order:
1. Exactly one ghostflow error
2. The error is the "root commit not allowed" form
3. The flagged SHA equals the side branch's tail commit
Any of these are real failures that must be fixed:
- More than one ghostflow error
- A root-commit error pointing at any commit not on the
side branch
- Trailing-whitespace or missing-newline errors
For PR InsightSoftwareConsortium#6135 (and future ingests), reviewers should treat the
single "root commit" error as green -- it confirms the merge
topology was built correctly. Insisting on a fully-green
ghostflow would force re-flattening to a linear rebase, which
destroys the merge join and blame walk that the merge-topology
requirement was added to preserve.
…est-GenericLabelInterpolator ENH: Ingest ITKGenericLabelInterpolator into Modules/Filtering
The upstream remote module's top-level CMakeLists.txt carried a dual-mode preamble that supports both standalone (find_package(ITK) + ITKModuleExternal) and in-tree (itk_module_impl) builds. Once the module lives under Modules/Filtering/, only the in-tree branch is reachable -- the standalone branch is dead code, the cmake_minimum_required and project() lines duplicate what ITK's root CMake already owns. Collapse the file to a single itk_module_impl() call, matching every other in-tree Modules/<Group>/<Name>/ module. Per the standalone-build cleanup convention documented in Utilities/Maintenance/RemoteModuleIngest/INGESTION_STRATEGY.md under "Standalone-build boilerplate cleanup (modes A/B)" and applied previously to GenericLabelInterpolator (PR InsightSoftwareConsortium#6135) and MGHIO (PR InsightSoftwareConsortium#6137).
The module now lives at Modules/Filtering/FastBilateral/. The configure-time fetch declaration in Modules/Remote/ would otherwise clone the (soon-to-be-archived) upstream and double-define the module. Mirrors the in-tree transition completed for GenericLabelInterpolator (PR InsightSoftwareConsortium#6135) and MGHIO (PR InsightSoftwareConsortium#6137).
The normalize-ingest-commits.py script replays each non-merge upstream commit via cherry-pick and skips merges entirely. The result loses the upstream merge topology, which the strategy doc has always mandated as preserved. Reviewers flagged this on PRs InsightSoftwareConsortium#6135, InsightSoftwareConsortium#6137, InsightSoftwareConsortium#6159, and InsightSoftwareConsortium#6161 before it became a rule violation. This commit: 1. Adds a hard refuse-to-run guard to normalize-ingest-commits.py (exit 3 with deprecation notice unless --i-understand-this-linearizes is passed). The guard names the replacement and points at the strategy doc. 2. Adds rewrite-history-merge-preserving.py — a git-filter-repo driven rewriter that walks every commit (merges included) and applies uniform text-blob normalization (trailing-whitespace strip + EOF-newline fix). Implements the user-mandated Phase 1 reference / Phase 2 traversal / Phase 3 verification architecture. 3. Updates INGESTION_STRATEGY.md with the "Linearization is forbidden" subsection, an allowed-tool table for per-commit re-formatting, and the new operator check that the merge count satisfies 1 + UPSTREAM_INTERNAL_MERGES. Language-specific formatters (clang-format, gersemi) are intentionally NOT applied per blob — they require the destination's current config, and applying them retroactively across upstream history would produce spurious diffs. The recommended pattern is a single "STYLE: Apply current formatters" commit at the rewritten tip after Phase 2 succeeds.
Brings the
GenericLabelInterpolatorremote module in-tree atModules/Filtering/GenericLabelInterpolator/, following the same pattern used for #6093 (AnisotropicDiffusionLBR) and #6103 (Montage). 4-commit stack on top ofupstream/main; the upstream history is squashed into the ingest commit so each commit conforms to ITK's commit-quality rules.Commit stack (top → bottom)
The squashed
ENH: Ingestsnapshot is taken from upstream tagv1.3.1(commitfc78327939). The upstream history (~46 commits, dating to 2014) is preserved at https://github.com/InsightSoftwareConsortium/ITKGenericLabelInterpolator and is cross-referenced from the ingest commit message.What lives in-tree now
include/— 4 headersitkLabelImageGenericInterpolateImageFunction.{h,hxx}itkLabelSelectionImageAdaptor.hitkLabelSelectionPixelAccessor.htest/RotateLabels.cxx+ 2.cidcontent links (already in CID format upstream — no MD5/SHA512 migration needed)wrapping/itkLabelImageGenericInterpolateImageFunction.wrapitk-module.cmakerewritten to drop thefile(READ README.rst)call (README.rst is intentionally outside the whitelist; description is now inlined)Modules/Filtering/GenericLabelInterpolator/README.mdpointing at the (to-be-archived) upstreamGreptile findings addressed inline in the squashed ingest
\ingroup: removed the stray leading*so doxygen recognises the group tags.itk-module.cmake: added explicitITKImageFunctiontoDEPENDS(the production header#includesitkInterpolateImageFunction.h); removed the redundantITKImageFunctionfromTEST_DEPENDS.int icounter alongsidem_Labelsiterator" suggestion in the.hxxwas deferred — logic is correct, refactor is stylistic, better handled in a follow-up STYLE: PR after this lands.