threads / discuss / 59574

Re: 'git config --edit' unexpected behavior

Subject: Re: 'git config --edit' unexpected behavior

## tl;dr

2 messages between Apr 10, 2023 and Apr 11, 2023.

replies: 1people: 2as markdown or json

Mervin Guy· Apr 10, 2023, 23:05 UTC · lore
I'm confident there is an error in the `git config --global -e` pipeline though (very likely git.c), because when using git-aliases the function performs as expected.
My current alias `ec` pointing to the command `!vi $HOME/.gitconfig` - where $HOME is `/root`. The full command looks like `git ec` and works as expected.
Meaning that the only difference between the failed-run and successful-run was calling the git built-in `git config --global -e`.
Show 26 quoted lines
> On Apr 10, 2023, at 16:49, Hello World! <mail@mervin.works> wrote:
> 
> Using the command, the trace says it’s using 'vi /root/.gitconfig' - which is indeed the set editor.
> 
> For more verbosity, the call-chain is 'git.c' (trace: built-in: git config) → 'run_command.c' (trace: run_command: 'vi /root/.gitconfig') which doesn’t seem strange.
>>> On Apr 10, 2023, at 16:25, Jeff King <peff@peff.net> wrote:
>>>  On Mon, Apr 10, 2023 at 03:44:26PM -0400, Mervin Guy wrote:
>>> 
>>> What did you do before the bug happened? (Steps to reproduce your issue)
>>> - Changed my directory to a git-repo I was working on, using 'cd <directory_name>'. Then I ran 'git config --global -e'.
>>> What did you expect to happen? (Expected behavior)
>>> - I exepected the command to display my current-config file, with all settings included, in my editor.
>>> What happened instead? (Actual behavior)
>>> - My config-file was overwritten and displayed a default-setup message, the config-file was lost after this point.
>>> I experimented with different ways of activating the command, but they all led to an overwrite of the file.
>> 
>> That's certainly unexpected. "git config --global -e" works fine for me.
>> And Git itself won't overwrite the file; it will run your editor with
>> the name of the file, and the editor is responsible for any writing.
>> Which editor are you trying to use? Can you try running with:
>> 
>> GIT_TRACE=1 git config --global -e
>> 
>> which should show the editor command that Git runs.
>> 
>> -Peff
Jeff King· Apr 11, 2023, 09:41 UTC · re: Mervin Guy · lore
On Mon, Apr 10, 2023 at 07:05:12PM -0400, Mervin Guy wrote:
Show 10 quoted lines
> I'm confident there is an error in the `git config --global -e`
> pipeline though (very likely git.c), because when using git-aliases
> the function performs as expected.
> 
> My current alias `ec` pointing to the command `!vi $HOME/.gitconfig` -
> where $HOME is `/root`. The full command looks like `git ec` and works
> as expected.
> 
> Meaning that the only difference between the failed-run and
> successful-run was calling the git built-in `git config --global -e`.

OK, so we can guess it has to do with the "--edit" option specifically, and your editor is doing what we'd expect. The main thing that code is doing is just opening the editor, but there's this curious bit of code before it does so:

  $ sed -ne '851,+11p' builtin/config.c
  		if (use_global_config) {
  			int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
  			if (fd >= 0) {
  				char *content = default_user_config();
  				write_str_in_full(fd, content);
  				free(content);
  				close(fd);
  			}
  			else if (errno != EEXIST)
  				die_errno(_("cannot create configuration file %s"), config_file);
  		}
  		launch_editor(config_file, NULL, NULL);

That shouldn't be overwriting your existing file, since O_EXCL will refuse to open the file in that case.

But I wonder if something funny is going on with the file selection. We support both the traditional $HOME/.gitconfig location, but also the xdg location (usually $HOME/.config/git/config, but $XDG_CONFIG_HOME can tweak that).

When reading config for most commands, we will generally pull from both sources. But for "git config --global", we have to pick one to operate on, both for reading and writing. The logic is supposed to prefer $HOME/.gitconfig, but use the xdg location if it exists and the $HOME one doesn't.

From your output:
> > Using the command, the trace says it’s using 'vi /root/.gitconfig' -
> > which is indeed the set editor.

it's picking the $HOME one. You said you had previous contents that were overwritten. How did you add them originally, and might they have been in the xdg location? Can you see if there is anything in /root/.config/git?

I admit I still don't know how we'd trigger this case; if the file did exist then we should never use /root/.config in the first place.

Another left-field possibility: is /root on an unusual filesystem (e.g., a networked one) where O_EXCL might not behave as it should?

-Peff

← back to recent threads