{"thread":{"id":"58311","subject":"bugreport: \"git config --global\" fails if an invalid .git file present","startedAt":"2022-08-16T16:17:06Z","lastAt":"2022-08-24T11:34:43Z","messageCount":4,"participants":["Jinwook Jeong","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"461294","messageId":"CAA3Q-aYfn0om2tXjwH-9ayaX57Yj6xkKw1hpi2asthgHvWovsw@mail.gmail.com","threadId":"58311","inReplyTo":null,"subject":"bugreport: \"git config --global\" fails if an invalid .git file present","fromName":"Jinwook Jeong","fromEmail":"vustthat@gmail.com","sentAt":"2022-08-16T16:16:44Z","receivedAt":"2022-08-16T16:17:06Z","isPatch":false,"sender":{"key":"vustthat@gmail.com","avatar":null},"body":"What did you do before the bug happened? (Steps to reproduce your issue)\n\nExecuting `git config --global ...` and $PWD/.git exists as a file and\nis invalid.\n\nWhat did you expect to happen? (Expected behavior)\n\nGit reads from or writes to the global config store.\n\nWhat happened instead? (Actual behavior)\n\nIt prints:\n  fatal: invalid gitfile format: $PWD/.git\n\nWhat's different between what you expected and what actually happened?\n\nGit fails to access the global config even if the current directory's\n`.git` file has nothing to do with the global config.\n\n[System Info]\ngit version:\ngit version 2.37.2\ncpu: arm64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nfeature: fsmonitor--daemon\nuname: Darwin 21.6.0 Darwin Kernel Version 21.6.0: Sat Jun 18 17:07:22\nPDT 2022; root:xnu-8020.140.41~1/RELEASE_ARM64_T6000 arm64\ncompiler info: clang: 13.1.6 (clang-1316.0.21.2.5)\nlibc info: no libc information available\n$SHELL (typically, interactive shell): /opt/homebrew/bin/bash\n\n\n[Enabled Hooks]\nnot run from a git repository - no hooks to show\n"},{"id":"461398","messageId":"Yv3ZKcD0L0dSIavr@coredump.intra.peff.net","threadId":"58311","inReplyTo":"CAA3Q-aYfn0om2tXjwH-9ayaX57Yj6xkKw1hpi2asthgHvWovsw@mail.gmail.com","subject":"Re: bugreport: \"git config --global\" fails if an invalid .git file present","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2022-08-18T06:16:09Z","receivedAt":"2022-08-18T06:16:15Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Aug 17, 2022 at 01:16:44AM +0900, Jinwook Jeong wrote:\n\n> What did you do before the bug happened? (Steps to reproduce your issue)\n> \n> Executing `git config --global ...` and $PWD/.git exists as a file and\n> is invalid.\n> \n> What did you expect to happen? (Expected behavior)\n> \n> Git reads from or writes to the global config store.\n> \n> What happened instead? (Actual behavior)\n> \n> It prints:\n>   fatal: invalid gitfile format: $PWD/.git\n> \n> What's different between what you expected and what actually happened?\n> \n> Git fails to access the global config even if the current directory's\n> `.git` file has nothing to do with the global config.\n\nI agree this isn't entirely friendly, but I think things are working as\ndesigned. Even though you're only asking to change global config, we do\nstill speculatively check for a repository when running git-config at\nall, as various options could impact its behavior. So the backtrace\nlooks like this:\n\n  0  die (err=0x5555558e5c33 \"invalid gitfile format: %s\") at usage.c:175\n  #1  0x00005555557fbc87 in read_gitfile_error_die (error_code=5, path=0x5555559abbd0 \"/home/peff/.git\", dir=0x0)\n      at setup.c:786\n  #2  0x00005555557fbfaa in read_gitfile_gently (path=0x5555559abbd0 \"/home/peff/.git\", return_error_code=0x0)\n      at setup.c:875\n  #3  0x00005555557fce4d in setup_git_directory_gently_1 (dir=0x7fffffffe160, gitdir=0x7fffffffe140,\n      report=0x7fffffffe120, die_on_error=1) at setup.c:1298\n  #4  0x00005555557fd4d6 in setup_git_directory_gently (nongit_ok=0x7fffffffe1ec) at setup.c:1455\n  #5  0x0000555555574a32 in run_builtin (p=0x55555596e9f0 <commands+624>, argc=4, argv=0x7fffffffe570) at git.c:436\n  #6  0x000055555557505f in handle_builtin (argc=4, argv=0x7fffffffe570) at git.c:720\n\nand when we hit the error, we have not even started running code\nspecific to git-config, let alone seen that the \"--global\" option is in\nuse.\n\nThere's another more subtle question lurking here. The config builtin is\nmarked as RUN_SETUP_GENTLY, so it will run even if we are not inside a\nrepository at all. But you can see in the backtrace above that we pass\ndie_on_error=1 to setup_git_directory_gently_1(). That is, the \"gentle\"\nform here means \"it is OK not to be in a repository\", but if we see\nsomething that indicates we should be in a repository (like a .git\nfile), but we hit an error examining it, we bail immediately. We _could_\nsay \"well, it's not a valid .git file, let's keep looking\".\n\nAnd that would make your case Just Work. But it's also more dangerous;\nif a misconfiguration or transient error caused us to set up an\nunexpected environment, then the results could be quite wrong and\nconfusing. Maybe less so for \"git config\", but for destructive\noperations it's a scarier concept.\n\nSo a patch like the one below does what you want, but I'm not sure it's\na good idea for the reasons given above.\n\nIn your case, the right resolution is probably to delete the bogus .git\nfile.\n\n-Peff\n\n---\ndiff --git a/setup.c b/setup.c\nindex cefd5f63c4..aafb1e1e99 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -1452,7 +1452,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\tdie_errno(_(\"Unable to read current working directory\"));\n \tstrbuf_addbuf(&dir, &cwd);\n \n-\tswitch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {\n+\tswitch (setup_git_directory_gently_1(&dir, &gitdir, &report, !nongit_ok)) {\n \tcase GIT_DIR_EXPLICIT:\n \t\tprefix = setup_explicit_git_dir(gitdir.buf, &cwd, &repo_fmt, nongit_ok);\n \t\tbreak;\n@@ -1503,6 +1503,11 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t}\n \t\t*nongit_ok = 1;\n \t\tbreak;\n+\tcase GIT_DIR_INVALID_GITFILE:\n+\t\tif (!nongit_ok)\n+\t\t\tBUG(\"read_gitfile_gently() should have died on error\");\n+\t\t*nongit_ok = 1;\n+\t\tbreak;\n \tcase GIT_DIR_NONE:\n \t\t/*\n \t\t * As a safeguard against setup_git_directory_gently_1 returning\n"},{"id":"461437","messageId":"xmqq35dtseht.fsf@gitster.g","threadId":"58311","inReplyTo":"Yv3ZKcD0L0dSIavr@coredump.intra.peff.net","subject":"Re: bugreport: \"git config --global\" fails if an invalid .git file present","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-08-18T16:28:14Z","receivedAt":"2022-08-18T16:28:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> And that would make your case Just Work. But it's also more dangerous;\n> if a misconfiguration or transient error caused us to set up an\n> unexpected environment, then the results could be quite wrong and\n> confusing. Maybe less so for \"git config\", but for destructive\n> operations it's a scarier concept.\n\nThat is a good point, especially if destructive command is run in a\nrepository the user didn't mean to run it in, it would not be\npretty.\n\n> In your case, the right resolution is probably to delete the bogus .git\n> file.\n\nYup, that was what I said in a draft I wrote a few days ago and\nstill in my outbox ;-)\n"},{"id":"461893","messageId":"CAA3Q-aZmn+K2n3PnLixLfAmf78FkQqCneBkzyd+edXMXSoy2MA@mail.gmail.com","threadId":"58311","inReplyTo":"xmqq35dtseht.fsf@gitster.g","subject":"Re: bugreport: \"git config --global\" fails if an invalid .git file present","fromName":"Jinwook Jeong","fromEmail":"vustthat@gmail.com","sentAt":"2022-08-24T11:34:19Z","receivedAt":"2022-08-24T11:34:43Z","isPatch":false,"sender":{"key":"vustthat@gmail.com","avatar":null},"body":"On Thu, Aug 18, 2022 at 3:16 PM Jeff King <peff@peff.net> wrote:\n\n> I agree this isn't entirely friendly, but I think things are working as\n> designed. Even though you're only asking to change global config, we do\n> still speculatively check for a repository when running git-config at\n> all, as various options could impact its behavior. So the backtrace\n> looks like this:\n\nI didn't know that a local repository could affect the result of \"git\nconfig --global\".\n\nThank you for the detailed explanation!\n"}]}