pygit2 icon indicating copy to clipboard operation
pygit2 copied to clipboard

Global config cannot be set if ~/.gitconfig does not exist yet

Open MarcelWaldvogel opened this issue 6 years ago • 3 comments

When there is no ~/.gitconfig, the following code snippet

import pygit2
global_config = pygit2.Config.get_global_config() # ← Exception raised here
global_config['user.email'] = '[email protected]'

fails with

Traceback (most recent call last):
  File "global_config.py", line 2, in <module>
    global_config = pygit2.Config.get_global_config()
  File "/usr/lib/python3/dist-packages/pygit2/config.py", line 281, in get_global_config
    return Config._from_found_config(C.git_config_find_global)
  File "/usr/lib/python3/dist-packages/pygit2/config.py", line 265, in _from_found_config
    check_error(err, True)
  File "/usr/lib/python3/dist-packages/pygit2/errors.py", line 53, in check_error
    raise IOError(message)
OSError: the global file '.gitconfig' doesn't exist: No such file or directory

I.e.,

  1. there seems to be no way of setting a global option unless ~/.gitconfig already exists.
  2. There seems to be no way to create the global config file ahead of time, at least not in a portable way (I doubt it is in ~/.gitconfig on Windows systems).

MarcelWaldvogel avatar Jun 12 '19 19:06 MarcelWaldvogel

I am considering adding an option to create the config file if needed. The plan is to add a create=True option to Config.__init__() and Config.get_*_config(). The latter would pass it on to the former, which would then open(path, 'a') just before the call to C.git_config_open_ondisk().

Would this be an acceptable way or would you prefer going another route? Or should I call C.git_config_add_file_ondisk() (which seems to be the right function to use, but it is not directly obvious how to use it)?

MarcelWaldvogel avatar Jun 16 '19 13:06 MarcelWaldvogel

Probably the Config.get_*_config() functions should check for GIT_ENOTFOUND and then return None instead of raising an error. What do you think?

Then I'm OK with your suggestion to add a create option, if it defaults to false, create=False. I don't think you need to call git_config_add_file_ondisk, you can just create the empty file and then open it. To know the path to the file to create you will need to use something like:

pygit2.option(pygit2.GIT_OPT_GET_SEARCH_PATH, pygit2.GIT_CONFIG_LEVEL_GLOBAL)

And then append the proper filename.

jdavid avatar Jun 18 '19 20:06 jdavid

I do not see any benefit in returning None, as it will still require special-case treatment. Changing the existing semantics will also cause more special-case treatment, as now users of pygit2 would need to test for None as well as for the exception.

Having a create parameter (defaulting to False, of course) however obviates the need for the None/try/except handling in this case. I will submit a pull request.

Thanks for the pygit2.option pointer!

MarcelWaldvogel avatar Jun 19 '19 12:06 MarcelWaldvogel