diff --git a/pkg/yqlib/operator_anchors_aliases_test.go b/pkg/yqlib/operator_anchors_aliases_test.go index d1ca5e6d..9d9c5ed6 100644 --- a/pkg/yqlib/operator_anchors_aliases_test.go +++ b/pkg/yqlib/operator_anchors_aliases_test.go @@ -319,6 +319,18 @@ somethingElse: ` var anchorOperatorScenarios = []expressionScenario{ + { + // mergeObjects previously skipped all !!merge-tagged nodes. Since !!merge only appears on + // << map keys, this meant applyAssignment was never called for the << key. It was later + // autocreated by createStringScalarNode("<<") with tag !!str, silently dropping !!merge. + // DontFollowAlias:true already prevents aliases being followed, so the skip was redundant. + // Old (buggy) output: "D0, P[], (!!map)::base: &base\n x: 1\ndest:\n <<: *base\n" + skipDoc: true, + description: "direct *+ preserves explicit !!merge tag on << key (regression for issue 2677)", + document: "base: &base\n x: 1\ndest:\n !!merge <<: *base\n", + expression: `. as $d | {} *+ $d`, + expected: []string{"D0, P[], (!!map)::base: &base\n x: 1\ndest:\n !!merge <<: *base\n"}, + }, { skipDoc: true, description: "explicit !!merge tag on << key is preserved through ireduce merge", diff --git a/pkg/yqlib/operator_multiply.go b/pkg/yqlib/operator_multiply.go index a09b7c49..dc69c57f 100644 --- a/pkg/yqlib/operator_multiply.go +++ b/pkg/yqlib/operator_multiply.go @@ -189,10 +189,6 @@ func mergeObjects(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs log.Debugf("going to applied assignment to LHS: %v with RHS: %v", NodeToString(lhs), NodeToString(candidate)) - if candidate.Tag == "!!merge" && !candidate.IsMapKey { - continue - } - err := applyAssignment(d, context, pathIndexToStartFrom, lhs, candidate, preferences) if err != nil { return nil, err