docstr: Merge config b into a
  
  :param a: target config
  :type a: ConfigTree
  :param b: source config
  :type b: ConfigTree
  :return: merged config a
docstr_tok: ["Merge","config","b","into","a",":","param","a",":","target","config",":","type","a",":","ConfigTree",":","param","b",":","source","config",":","type","b",":","ConfigTree",":","return",":","merged","config","a"]
code: 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
  
imports: from collections import OrderedDict
  from pyparsing import lineno
  from pyparsing import col
  import re
  import copy
  from .exceptions import ConfigException, ConfigWrongTypeException, ConfigMissingException
label_desc: Use image node_id 2 for calling the ConfigTree obj's underlying member method code with example usage: obj.merge_configs(a, b, copy_trees) and returns: a