2020 defenc ,
2121 force_text ,
2222 with_metaclass ,
23- PY3
23+ PY3 ,
24+ is_win ,
2425)
2526from git .util import LockFile
2627
4041log = logging .getLogger ('git.config' )
4142log .addHandler (logging .NullHandler ())
4243
44+ # invariants
45+ # represents the configuration level of a configuration file
46+ CONFIG_LEVELS = ("system" , "user" , "global" , "repository" )
47+
4348
4449class MetaParserBuilder (abc .ABCMeta ):
4550
@@ -191,6 +196,26 @@ def items_all(self):
191196 return [(k , self .getall (k )) for k in self ]
192197
193198
199+ def get_config_path (config_level ):
200+
201+ # we do not support an absolute path of the gitconfig on windows ,
202+ # use the global config instead
203+ if is_win and config_level == "system" :
204+ config_level = "global"
205+
206+ if config_level == "system" :
207+ return "/etc/gitconfig"
208+ elif config_level == "user" :
209+ config_home = os .environ .get ("XDG_CONFIG_HOME" ) or osp .join (os .environ .get ("HOME" , '~' ), ".config" )
210+ return osp .normpath (osp .expanduser (osp .join (config_home , "git" , "config" )))
211+ elif config_level == "global" :
212+ return osp .normpath (osp .expanduser ("~/.gitconfig" ))
213+ elif config_level == "repository" :
214+ raise ValueError ("repository configuration level not allowed" )
215+
216+ ValueError ("Invalid configuration level: %r" % config_level )
217+
218+
194219class GitConfigParser (with_metaclass (MetaParserBuilder , cp .RawConfigParser , object )):
195220
196221 """Implements specifics required to read git style configuration files.
@@ -229,7 +254,7 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, obje
229254 # list of RawConfigParser methods able to change the instance
230255 _mutating_methods_ = ("add_section" , "remove_section" , "remove_option" , "set" )
231256
232- def __init__ (self , file_or_files , read_only = True , merge_includes = True ):
257+ def __init__ (self , file_or_files = None , read_only = True , merge_includes = True , config_level = None ):
233258 """Initialize a configuration reader to read the given file_or_files and to
234259 possibly allow changes to it by setting read_only False
235260
@@ -251,7 +276,17 @@ def __init__(self, file_or_files, read_only=True, merge_includes=True):
251276 if not hasattr (self , '_proxies' ):
252277 self ._proxies = self ._dict ()
253278
254- self ._file_or_files = file_or_files
279+ if file_or_files is not None :
280+ self ._file_or_files = file_or_files
281+ else :
282+ if config_level is None :
283+ if read_only :
284+ self ._file_or_files = [get_config_path (f ) for f in CONFIG_LEVELS [:- 1 ]]
285+ else :
286+ raise ValueError ("No configuration level or configuration files specified" )
287+ else :
288+ self ._file_or_files = [get_config_path (config_level )]
289+
255290 self ._read_only = read_only
256291 self ._dirty = False
257292 self ._is_initialized = False
0 commit comments