def merge_configs(a, b, copy_trees=False):
        """Merge config b into a

        :param a: target config
        :type a: ConfigTree
        :param b: source config
        :type b: ConfigTree
        :return: merged config a
        """
        for key, value in b.items():
            # if key is in both a and b and both values are dictionary then merge it otherwise override it
            if key in a and isinstance(a[key], ConfigTree) and isinstance(b[key], ConfigTree):
                if copy_trees:
                    a[key] = a[key].copy()
                ConfigTree.merge_configs(a[key], b[key], copy_trees=copy_trees)
            else:
                if isinstance(value, ConfigValues):
                    value.parent = a
                    value.key = key
                    if key in a:
                        value.overriden_value = a[key]
                a[key] = value
                if a.root:
                    if b.root:
                        a.history[key] = a.history.get(key, []) + b.history.get(key, [value])
                    else:
                        a.history[key] = a.history.get(key, []) + [value]

        return a
def merge_configs ( a , b , copy_trees = False ) : for key , value in b . items ( ) : if key in a and isinstance ( a [ key ] , ConfigTree ) and isinstance ( b [ key ] , ConfigTree ) : if copy_trees : a [ key ] = a [ key ] . copy ( ) ConfigTree . merge_configs ( a [ key ] , b [ key ] , copy_trees = copy_trees ) else : if isinstance ( value , ConfigValues ) : value . parent = a value . key = key if key in a : value . overriden_value = a [ key ] a [ key ] = value if a . root : if b . root : a . history [ key ] = a . history . get ( key , [ ] ) + b . history . get ( key , [ value ] ) else : a . history [ key ] = a . history . get ( key , [ ] ) + [ value ] return a
Merge config b into a

        :param a: target config
        :type a: ConfigTree
        :param b: source config
        :type b: ConfigTree
        :return: merged config a