{"thread":{"id":"66041","subject":"git config: unintuitive behaviour with --global and --no-includes","startedAt":"2026-07-20T10:02:14Z","lastAt":"2026-07-21T11:53:41Z","messageCount":5,"participants":["Hendrik Jaeger","Ben Knoble","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"548668","messageId":"20260720113402.0dc16abe@frustcomp.hnjs.home.arpa","threadId":"66041","inReplyTo":null,"subject":"git config: unintuitive behaviour with --global and --no-includes","fromName":"Hendrik Jaeger","fromEmail":"ml_git@henk.geekmail.org","sentAt":"2026-07-20T09:34:02Z","receivedAt":"2026-07-20T10:02:14Z","isPatch":false,"body":"Hi\n\nI ran into a problem working with lbmk (https://codeberg.org/libreboot/lbmk).\nTo see whether git is correctly configured, it runs `git config --global user.name` and that failed for my setup.\nThe reason is that I have user.name and user.email not directly in the normal git config file but in an included file and when given a scope like --global `git config` does not by default check included files.\n\nI tried to create a commented minimal example showing the problem with that:\n\n```\n# no config exists\n~ % cat .gitconfig\ncat: .gitconfig: No such file or directory\n~ % cat .gitconfig_personal\ncat: .gitconfig_personal: No such file or directory\n~ % ls ~/.config/git\nls: cannot access '/home/resu/.config/git': No such file or directory\n\n# config var is not set\n~ % git config --show-scope --show-origin user.name\n\n# set user.name\n~ % git config --global user.name \"Hendrik Jäger\"\n\n# check if it is set\n~ % cat .gitconfig\n[user]\n        name = Hendrik Jäger\n\n# check where it is set\n~ % git config --show-scope --show-origin user.name\nglobal  file:/home/resu/.gitconfig      Hendrik Jäger\n\n# check whether we can still retrieve it when explicitly giving the scope\n~ % git config --show-scope --show-origin --global user.name\nglobal  file:/home/resu/.gitconfig      Hendrik Jäger\n\n# move setting to non-standard file\n~ % cat .gitconfig > .gitconfig_personal\n\n# include that non-standard file\n~ % echo '[include]\\npath = .gitconfig_personal' >| .gitconfig\n\n# check config status\n~ % cat .gitconfig\n[include]\npath = .gitconfig_personal\n~ % cat .gitconfig_personal\n[user]\n        name = Hendrik Jäger\n\n# check whether git still finds that setting\n~ % git config --show-scope --show-origin user.name\nglobal  file:/home/resu/.gitconfig_personal     Hendrik Jäger\n\n# check whether git still finds that setting in the scope it is in\n~ % git config --show-scope --show-origin --global user.name\n\n# set it again in the global scope\n~ % git config --global user.name \"Henk Hunter\"\n\n# check again\n~ % git config --show-scope --show-origin user.name\nglobal  file:/home/resu/.gitconfig      Henk Hunter\n\n# check again with specific scope\n~ % git config --show-scope --show-origin --global user.name\nglobal  file:/home/resu/.gitconfig      Henk Hunter\n\n# reset git config and check if the setting is really gone\n~ % rm .gitconfig\n~ % git config --show-scope --show-origin user.name\n\n# set it again in global scope with different value\n~ % git config --global user.name \"Henk Hunter\"\n\n# check whether setting it was successful\n~ % git config --show-scope --show-origin user.name\nglobal  file:/home/resu/.gitconfig      Henk Hunter\n\n# check again with specific scope\n~ % git config --show-scope --show-origin --global user.name\nglobal  file:/home/resu/.gitconfig      Henk Hunter\n\n# add the include back\n~ % echo '[include]\\npath = .gitconfig_personal' >> .gitconfig\n\n# check config status\n~ % cat .gitconfig\n[user]\n        name = Henk Hunter\n[include]\npath = .gitconfig_personal\n\n# check the value and from which scope it comes\n~ % git config --show-scope --show-origin user.name\nglobal  file:/home/resu/.gitconfig_personal     Hendrik Jäger\n\n# check again with specific scope\n~ % git config --show-scope --show-origin --global user.name\nglobal  file:/home/resu/.gitconfig      Henk Hunter\n\n# check again while allowing includes\n~ % git config --show-scope --show-origin --includes user.name\nglobal  file:/home/resu/.gitconfig_personal     Hendrik Jäger\n~ % git config --show-scope --show-origin --global --includes user.name\nglobal  file:/home/resu/.gitconfig_personal     Hendrik Jäger\n```\n\nThe manpage says:\n> Respect include.*  directives in config files when looking up values. Defaults to off when a specific file is given (e.g., using --file, --global, etc) and on when searching all config files.\n\nIMHO it makes sense the way it is phrased “when a specific file is given” but then seems to turn into non-sense when --global is given as an example. Giving --global is not “giving a specific file” but “restricting to a specific scope”, which may `include` other files.\nThe results seem inconsistent and counterintuitive to me.\n\nAm I misunderstanding anything here?\nIs this behaviour intended?\nIf it is intended, can someone please explain the rationale behind it? I don’t get it, it seems wrong to me.\n\nRegarding the initial issue: I just added --includes to the call in lbmk and it works just fine, so there is no need to address this. I only mentioned it for context to how I got to looking into this behaviour.\nIf any relevant information is missing in this bugreport, I’ll be happy to add it, please let me know!\n\nThank you very much\n\nhenk\n"},{"id":"548678","messageId":"A5FBF044-4F91-456D-AD17-C3047DA0F973@gmail.com","threadId":"66041","inReplyTo":"20260720113402.0dc16abe@frustcomp.hnjs.home.arpa","subject":"Re: git config: unintuitive behaviour with --global and --no-includes","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-07-20T12:25:39Z","receivedAt":"2026-07-20T12:25:52Z","isPatch":false,"body":"\n> Le 20 juil. 2026 à 06:02, Hendrik Jaeger <ml_git@henk.geekmail.org> a écrit :\n> \n> ﻿Hi\n> \n> I ran into a problem working with lbmk (https://codeberg.org/libreboot/lbmk).\n> To see whether git is correctly configured, it runs `git config --global user.name` and that failed for my setup.\n> The reason is that I have user.name and user.email not directly in the normal git config file but in an included file and when given a scope like --global `git config` does not by default check included files.\n\n[snip]\n\n> Regarding the initial issue: I just added --includes to the call in lbmk and it works just fine, so there is no need to address this.\n\nI wonder why not use « git config user.name » without scope? That seems to sidestep the problem. Unless there’s a reason to use global-scope only? There’s also « git var GIT_AUTHOR_IDENT »."},{"id":"548679","messageId":"20260720125145.GA5100@coredump.intra.peff.net","threadId":"66041","inReplyTo":"20260720113402.0dc16abe@frustcomp.hnjs.home.arpa","subject":"Re: git config: unintuitive behaviour with --global and --no-includes","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-07-20T12:51:45Z","receivedAt":"2026-07-20T12:51:47Z","isPatch":false,"body":"On Mon, Jul 20, 2026 at 11:34:02AM +0200, Hendrik Jaeger wrote:\n\n> The manpage says:\n> > Respect include.*  directives in config files when looking up\n> > values. Defaults to off when a specific file is given (e.g., using\n> > --file, --global, etc) and on when searching all config files.\n> \n> IMHO it makes sense the way it is phrased “when a specific file is\n> given” but then seems to turn into non-sense when --global is given as\n> an example. Giving --global is not “giving a specific file” but\n> “restricting to a specific scope”, which may `include` other files.\n> The results seem inconsistent and counterintuitive to me.\n> \n> Am I misunderstanding anything here?\n> Is this behaviour intended?\n> If it is intended, can someone please explain the rationale behind it? I don’t get it, it seems wrong to me.\n\nThe behavior you're seeing is intended. Regarding \"a specific scope\", I\ndon't think that's an unreasonable way to think about it. But it's not\nhow Git thinks about it, and in particular back when --include was added\nand this behavior was set, \"--global\" was literally a synonym for\n\"--file=$HOME/.gitconfig\".\n\nAs for the rationale, it is a mix of backwards compatibility and\nleast-surprise. The include functionality was tacked on to the existing\nconfig parser, and we did not want to surprise anybody who asked for a\nspecific file by showing them results for another file. This is\nespecially important for reading untrusted input like .gitmodules, but\nalso for writing.\n\n> Regarding the initial issue: I just added --includes to the call in\n> lbmk and it works just fine, so there is no need to address this. I\n> only mentioned it for context to how I got to looking into this\n> behaviour.\n\nIMHO lbmk is wrong to be using \"--global\" in the first place. Looking at\nthe source, it is trying to check whether the user has set up their\nidentity. But it is not lbmk's business whether you did it in the\n--global config file, or elsewhere! So it should probably just use a\nstraight \"git config user.name\", which will do the same resolution that\nGit will do internally.\n\nThe \"--global\" was added in their 4a280c62 (.gitcheck: re-write\nentirely. force global config., 2023-08-27), but I don't see any\nrationale given.\n\nDepending on what they are trying to check, it might be even better\nstill for it to use \"git var GIT_AUTHOR_IDENT\". That will give the\nactual ident Git will derive, including things like checking $EMAIL in\nthe environment and so on.\n\nSo if the intent is \"will Git come up with some ident\", then that is the\nmost accurate way to check it. But if the intent is \"did the user\nspecifically configure Git (because we are worried that values derived\nfrom GECOS and $EMAIL might not be accurate)\", then checking user.*\nspecifically is closer to that.\n\nThough note there is one other hitch, which is that the user can set\nauthor.* and committer.* as specific variables, since 39ab4d0951\n(config: allow giving separate author and committer idents, 2019-02-04).\nI suspect not many people do that, but that would also be something that\na config-specific check would have to handle (but \"git var\" would do\nautomatically).\n\nSo I think you might consider sending a bug report to lbmk. Feel free to\npoint at this thread, and I'm happy to discuss further with them.\n\n-Peff\n"},{"id":"548685","messageId":"xmqqse5dd1vz.fsf@gitster.g","threadId":"66041","inReplyTo":"20260720125145.GA5100@coredump.intra.peff.net","subject":"Re: git config: unintuitive behaviour with --global and --no-includes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-07-20T17:09:04Z","receivedAt":"2026-07-20T17:09:08Z","isPatch":false,"body":"Jeff King <peff@peff.net> writes:\n\n> IMHO lbmk is wrong to be using \"--global\" in the first place. Looking at\n> the source, it is trying to check whether the user has set up their\n> identity. But it is not lbmk's business whether you did it in the\n> --global config file, or elsewhere!\n\nExactly.\n\n> Though note there is one other hitch, which is that the user can set\n> author.* and committer.* as specific variables, since 39ab4d0951\n> (config: allow giving separate author and committer idents, 2019-02-04).\n> I suspect not many people do that, but that would also be something that\n> a config-specific check would have to handle (but \"git var\" would do\n> automatically).\n>\n> So I think you might consider sending a bug report to lbmk. Feel free to\n> point at this thread, and I'm happy to discuss further with them.\n\nThanks for your thoughtful and thorough explanation.\n\nThe environment variables 'GIT_{AUTHOR,COMMITTER}_{NAME,EMAIL}' also\nplay a part in determining the author andcommitter identities, so\n'git var AUTHOR_IDENT' would be the correct choice here.\n\n\n"},{"id":"548720","messageId":"20260721135317.4802ef2d@frustcomp.hnjs.home.arpa","threadId":"66041","inReplyTo":"20260720125145.GA5100@coredump.intra.peff.net","subject":"Re: git config: unintuitive behaviour with --global and --no-includes","fromName":"Hendrik Jaeger","fromEmail":"ml_git@henk.geekmail.org","sentAt":"2026-07-21T11:53:17Z","receivedAt":"2026-07-21T11:53:41Z","isPatch":false,"body":"Hi Jeff\n\nThanks for your email!\n\n> As for the rationale, it is a mix of backwards compatibility and least-surprise.\n\nTo be honest, this reminds me of the XKCD comic with the title \"workflow\": https://xkcd.com/1172/\nThe behaviour may be “least-surprise” for the initiated. For everyone new to this, I’d expect it to be as “most-surprising” as it was for me.\n\nBest regards\n\nhenk\n\n\nOn Mon, 20 Jul 2026 08:51:45 -0400\nJeff King <peff@peff.net> wrote:\n\n> On Mon, Jul 20, 2026 at 11:34:02AM +0200, Hendrik Jaeger wrote:\n> \n> > The manpage says:  \n> > > Respect include.*  directives in config files when looking up\n> > > values. Defaults to off when a specific file is given (e.g., using\n> > > --file, --global, etc) and on when searching all config files.  \n> > \n> > IMHO it makes sense the way it is phrased “when a specific file is\n> > given” but then seems to turn into non-sense when --global is given as\n> > an example. Giving --global is not “giving a specific file” but\n> > “restricting to a specific scope”, which may `include` other files.\n> > The results seem inconsistent and counterintuitive to me.\n> > \n> > Am I misunderstanding anything here?\n> > Is this behaviour intended?\n> > If it is intended, can someone please explain the rationale behind it? I don’t get it, it seems wrong to me.  \n> \n> The behavior you're seeing is intended. Regarding \"a specific scope\", I\n> don't think that's an unreasonable way to think about it. But it's not\n> how Git thinks about it, and in particular back when --include was added\n> and this behavior was set, \"--global\" was literally a synonym for\n> \"--file=$HOME/.gitconfig\".\n> \n> As for the rationale, it is a mix of backwards compatibility and\n> least-surprise. The include functionality was tacked on to the existing\n> config parser, and we did not want to surprise anybody who asked for a\n> specific file by showing them results for another file. This is\n> especially important for reading untrusted input like .gitmodules, but\n> also for writing.\n> \n> > Regarding the initial issue: I just added --includes to the call in\n> > lbmk and it works just fine, so there is no need to address this. I\n> > only mentioned it for context to how I got to looking into this\n> > behaviour.  \n> \n> IMHO lbmk is wrong to be using \"--global\" in the first place. Looking at\n> the source, it is trying to check whether the user has set up their\n> identity. But it is not lbmk's business whether you did it in the\n> --global config file, or elsewhere! So it should probably just use a\n> straight \"git config user.name\", which will do the same resolution that\n> Git will do internally.\n> \n> The \"--global\" was added in their 4a280c62 (.gitcheck: re-write\n> entirely. force global config., 2023-08-27), but I don't see any\n> rationale given.\n> \n> Depending on what they are trying to check, it might be even better\n> still for it to use \"git var GIT_AUTHOR_IDENT\". That will give the\n> actual ident Git will derive, including things like checking $EMAIL in\n> the environment and so on.\n> \n> So if the intent is \"will Git come up with some ident\", then that is the\n> most accurate way to check it. But if the intent is \"did the user\n> specifically configure Git (because we are worried that values derived\n> from GECOS and $EMAIL might not be accurate)\", then checking user.*\n> specifically is closer to that.\n> \n> Though note there is one other hitch, which is that the user can set\n> author.* and committer.* as specific variables, since 39ab4d0951\n> (config: allow giving separate author and committer idents, 2019-02-04).\n> I suspect not many people do that, but that would also be something that\n> a config-specific check would have to handle (but \"git var\" would do\n> automatically).\n> \n> So I think you might consider sending a bug report to lbmk. Feel free to\n> point at this thread, and I'm happy to discuss further with them.\n> \n> -Peff\n"}]}