opscode/chef — pull request #1118 by sersut (2013-11-06 22:29:32+00:00)
Title: CHEF-4596 / CHEF-4631 : Pick the array that is higher in the precedence order instead of merging during deep merge

CHEF-4596: .to_hash sometimes unique-ifies internal arrays
CHEF-4631: to_hash returns all precedence instead of highest precedence

Two issues above point out that attribute merging behavior in Chef is not working according to customer expectations. Specifically when using to_hash method as explained in CHEF-4631.

This PR changes the behavior to concatenate attributes with array values if they are on the same precedence level and picks the value in the higher precedence level if merge is happening between precedence levels.

Also a new config options is introduced incase a user wants to continue using the old behavior.

With this change above two issues are fixed as below:
```ruby
chef > node.default['fb']['foo'] = {'foo' => ['a', 'b', 'a'], 'bar' => ['a', 'b', 'a']}
=> {"foo"=>["a", "b", "a"], "bar"=>["a", "b", "a"]}
chef > node['fb']['foo'].to_hash
=> {"foo"=>["a", "b", "a"], "bar"=>["a", "b", "a"]}
chef >
chef > node.default['example']['example_ssh']['users']['root']['authorized_princs'] = ['default']
=> ["default"]
chef > node.override['example']['example_ssh']['users']['root']['authorized_princs'] = ['override']
=> ["override"]
chef > node['example']['example_ssh']['users']['root'].to_hash['authorized_princs']
=> ["override"]
```

Similarly this change would mean that if an attribute is a hash that contains an array; and if this attribute is set in both override & default; the array with the highest precedence will win:

```ruby
chef > node.default['example'] = { 'foo' => [1, 2] }
=> {"foo"=>[1, 2]}
chef > node.override['example'] = { 'foo' => [1, 4] }
=> {"foo"=>[1, 4]}
chef > node['example']['foo']
=> [1, 4]
```