From 0a0627e12897cf560b488cc835d5a465f53935c2 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 22 Apr 2015 14:47:27 +0100 Subject: [PATCH 1/4] Windows: add support for a Windows-wide configuration Between the libgit2 and the Git for Windows project, there has been a discussion how we could share Git configuration to avoid duplication (or worse: skew). Earlier, libgit2 was nice enough to just re-use Git for Windows' C:\Program Files (x86)\Git\etc\gitconfig but with the upcoming Git for Windows 2.x, there would be more paths to search, as we will have 64-bit and 32-bit versions, and the corresponding config files will be in %PROGRAMFILES%\Git\mingw64\etc and ...\mingw32\etc, respectively. Worse: there are portable Git for Windows versions out there which live in totally unrelated directories, still. Therefore we came to a consensus to use `%PROGRAMDATA%\Git\config` as the location for shared Git settings that are of wider interest than just Git for Windows. On XP, there is no %PROGRAMDATA%, therefore we need to use "%ALLUSERSPROFILE%\Application Data\Git\config" in those setups. Of course, the configuration in `%PROGRAMDATA%\Git\config` has the widest reach, therefore it must take the lowest precedence, i.e. Git for Windows can still override settings in its `etc/gitconfig` file. Signed-off-by: Johannes Schindelin --- Documentation/config.txt | 4 +++- Documentation/git-config.txt | 5 +++++ Documentation/git.txt | 3 ++- compat/mingw.c | 19 +++++++++++++++++++ compat/mingw.h | 2 ++ config.c | 13 ++++++++++--- git-compat-util.h | 4 ++++ 7 files changed, 45 insertions(+), 5 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index cdcca81ec8..a93d6960ad 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -6,7 +6,9 @@ the Git commands' behavior. The `.git/config` file in each repository is used to store the configuration for that repository, and `$HOME/.gitconfig` is used to store a per-user configuration as fallback values for the `.git/config` file. The file `/etc/gitconfig` -can be used to store a system-wide default configuration. +can be used to store a system-wide default configuration. On Windows, +configuration can also be stored in `C:\ProgramData\Git\config`; This +file will be used also by libgit2-based software. The configuration variables are used by both the Git plumbing and the porcelains. The variables are divided into sections, wherein diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 18ddc78f42..807df740f0 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -281,6 +281,11 @@ $XDG_CONFIG_HOME/git/config:: $GIT_DIR/config:: Repository specific configuration file. +On Windows, as there is no central `/etc/` directory, there is yet another +config file, intended to contain settings for *all* Git-related software +running on the machine. Consequently, this config file takes an even lower +precedence than the `$(prefix)/etc/gitconfig` file. + If no further options are given, all reading options will read all of these files that are available. If the global or the system-wide configuration file are not available they will be ignored. If the repository configuration diff --git a/Documentation/git.txt b/Documentation/git.txt index dba7f0c18e..f54d4d1080 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -567,7 +567,8 @@ for further details. `GIT_CONFIG_NOSYSTEM`:: Whether to skip reading settings from the system-wide - `$(prefix)/etc/gitconfig` file. This environment variable can + `$(prefix)/etc/gitconfig` file (and on Windows, also from the + `%PROGRAMDATA%\Git\config` file). This environment variable can be used along with `$HOME` and `$XDG_CONFIG_HOME` to create a predictable environment for a picky script, or you can set it temporarily to avoid using a buggy `/etc/gitconfig` file while diff --git a/compat/mingw.c b/compat/mingw.c index abcf9ec734..e164adbb5a 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2568,3 +2568,22 @@ int uname(struct utsname *buf) "%u", (v >> 16) & 0x7fff); return 0; } + +const char *program_data_config(void) +{ + static struct strbuf path = STRBUF_INIT; + static unsigned initialized; + + if (!initialized) { + const char *env = mingw_getenv("PROGRAMDATA"); + const char *extra = ""; + if (!env) { + env = mingw_getenv("ALLUSERSPROFILE"); + extra = "/Application Data"; + } + if (env) + strbuf_addf(&path, "%s%s/Git/config", env, extra); + initialized = 1; + } + return *path.buf ? path.buf : NULL; +} diff --git a/compat/mingw.h b/compat/mingw.h index d8e077cbe2..26cc29f949 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -452,6 +452,8 @@ int mingw_offset_1st_component(const char *path); #define PATH_SEP ';' extern char *mingw_query_user_email(void); #define query_user_email mingw_query_user_email +extern const char *program_data_config(void); +#define git_program_data_config program_data_config #if !defined(__MINGW64_VERSION_MAJOR) && (!defined(_MSC_VER) || _MSC_VER < 1800) #define PRIuMAX "I64u" #define PRId64 "I64d" diff --git a/config.c b/config.c index 018df06379..8fd766588a 100644 --- a/config.c +++ b/config.c @@ -1653,9 +1653,16 @@ static int do_git_config_sequence(const struct config_options *opts, repo_config = NULL; current_parsing_scope = CONFIG_SCOPE_SYSTEM; - if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK, 0)) - ret += git_config_from_file(fn, git_etc_gitconfig(), - data); + if (git_config_system()) { + if (git_program_data_config() && + !access_or_die(git_program_data_config(), R_OK, 0)) + ret += git_config_from_file(fn, + git_program_data_config(), + data); + if (!access_or_die(git_etc_gitconfig(), R_OK, 0)) + ret += git_config_from_file(fn, git_etc_gitconfig(), + data); + } current_parsing_scope = CONFIG_SCOPE_GLOBAL; if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK)) diff --git a/git-compat-util.h b/git-compat-util.h index 039ed1dd4b..3935003aa9 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -396,6 +396,10 @@ static inline char *git_find_last_dir_sep(const char *path) #define query_user_email() NULL #endif +#ifndef git_program_data_config +#define git_program_data_config() NULL +#endif + #if defined(__HP_cc) && (__HP_cc >= 61000) #define NORETURN __attribute__((noreturn)) #define NORETURN_PTR From 97191332953a2f2a90e22c1d7cb97d10620886cf Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 16 Feb 2016 15:21:45 +0100 Subject: [PATCH 2/4] Clarify the location of the Windows-specific ProgramData config On Windows, there is no (single) `/etc/` directory. To address that, in conjunction with the libgit2 project, Git for Windows introduced yet another level of system-wide config files, located in C:\ProgramData (and the equivalent on Windows XP). Let's spell this out in the documentation. This closes https://github.com/git-for-windows/git/pull/470 (because there was no reaction in three months in that Pull Request). Signed-off-by: Johannes Schindelin --- Documentation/git-config.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 807df740f0..532dff7c09 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -282,9 +282,12 @@ $GIT_DIR/config:: Repository specific configuration file. On Windows, as there is no central `/etc/` directory, there is yet another -config file, intended to contain settings for *all* Git-related software -running on the machine. Consequently, this config file takes an even lower -precedence than the `$(prefix)/etc/gitconfig` file. +config file (located at `$PROGRAMDATA/Git/config`), intended to contain +settings for *all* Git-related software running on the machine. Consequently, +this config file takes an even lower precedence than the +`$(prefix)/etc/gitconfig` file. Typically `$PROGRAMDATA` points to +`C:\ProgramData` (on Windows XP the equivalent in `$ALLUSERSPROFILE` is used, +i.e. `C:\Documents and Settings\All Users\Application Data\Git\config`). If no further options are given, all reading options will read all of these files that are available. If the global or the system-wide configuration From adc6e7c88af862741c019fea286a2b40270c1d5a Mon Sep 17 00:00:00 2001 From: Andreas Heiduk Date: Mon, 15 May 2017 22:26:32 +0200 Subject: [PATCH 3/4] Remove support for XP specific config location Current Git for Windows supports an additional configuration location for system setting. On contemporary versionws of Windows this is $PROGRAMDATA/Git/config. But XP does not know about $PRORGRAMDATA so $ALLUSERSPROFILE/Application Data/Git/config was used. XP itself is EOL for quite some time and Git for Windows ceased to support it officially with version 2.10.0 (release 3 Sep 2016). https://github.com/git-for-windows/git/wiki/FAQ#which-versions-of-windows-are-supported https://git-for-windows.github.io/requirements.html Signed-off-by: Andreas Heiduk --- Documentation/git-config.txt | 3 +-- compat/mingw.c | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 532dff7c09..3e73b1bd22 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -286,8 +286,7 @@ config file (located at `$PROGRAMDATA/Git/config`), intended to contain settings for *all* Git-related software running on the machine. Consequently, this config file takes an even lower precedence than the `$(prefix)/etc/gitconfig` file. Typically `$PROGRAMDATA` points to -`C:\ProgramData` (on Windows XP the equivalent in `$ALLUSERSPROFILE` is used, -i.e. `C:\Documents and Settings\All Users\Application Data\Git\config`). +`C:\ProgramData`. If no further options are given, all reading options will read all of these files that are available. If the global or the system-wide configuration diff --git a/compat/mingw.c b/compat/mingw.c index e164adbb5a..88b05c71f9 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2576,13 +2576,8 @@ const char *program_data_config(void) if (!initialized) { const char *env = mingw_getenv("PROGRAMDATA"); - const char *extra = ""; - if (!env) { - env = mingw_getenv("ALLUSERSPROFILE"); - extra = "/Application Data"; - } if (env) - strbuf_addf(&path, "%s%s/Git/config", env, extra); + strbuf_addf(&path, "%s/Git/config", env); initialized = 1; } return *path.buf ? path.buf : NULL; From 2684f9bcf654d4751fe39535789f292eab2a1942 Mon Sep 17 00:00:00 2001 From: Andreas Heiduk Date: Mon, 15 May 2017 23:39:51 +0200 Subject: [PATCH 4/4] Improve documentation for C:\ProgramData\Git\config Move the description for the additional Git for Windows configuration file into the right place, so that the following descriptions of the read priority also covers this file correctly. Also make it clear, what file `git config --system` selects. Signed-off-by: Andreas Heiduk --- Documentation/git-config.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 3e73b1bd22..11242d8138 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -263,8 +263,16 @@ FILES If not set explicitly with `--file`, there are four files where 'git config' will search for configuration options: +$PROGRAMDATA/Git/config:: + (Windows-only) System-wide configuration file shared with other Git + implementations. Typically `$PROGRAMDATA` points to `C:\ProgramData`. + $(prefix)/etc/gitconfig:: System-wide configuration file. + (Windows-only) This file contains only the settings which are + specific for this installation of Git for Windows and which should + not be shared with other Git implementations like JGit, libgit2. + `--system` will select this file. $XDG_CONFIG_HOME/git/config:: Second user-specific configuration file. If $XDG_CONFIG_HOME is not set @@ -281,13 +289,6 @@ $XDG_CONFIG_HOME/git/config:: $GIT_DIR/config:: Repository specific configuration file. -On Windows, as there is no central `/etc/` directory, there is yet another -config file (located at `$PROGRAMDATA/Git/config`), intended to contain -settings for *all* Git-related software running on the machine. Consequently, -this config file takes an even lower precedence than the -`$(prefix)/etc/gitconfig` file. Typically `$PROGRAMDATA` points to -`C:\ProgramData`. - If no further options are given, all reading options will read all of these files that are available. If the global or the system-wide configuration file are not available they will be ignored. If the repository configuration