From a7c09059173b5d531bd05a99bde296fa323bbf3a 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 554b334964..b31869d202 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 e09ed5d7d5..f6e0e5318e 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -264,6 +264,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 4767860e72..5b7da12fcb 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -556,7 +556,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 2a0e7daacd..40be1a4827 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2569,3 +2569,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 2fd05aaa88..bd12125deb 100644 --- a/config.c +++ b/config.c @@ -1554,9 +1554,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 97e56c066a..4a5e724828 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -392,6 +392,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 d963e125851d7de2e347504fddc04eb78281ae62 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 f6e0e5318e..b961e0af7c 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -265,9 +265,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 145d8e23d61440c298f9a0157bfa2be21e95aa7a 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 b961e0af7c..864d285070 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -269,8 +269,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 40be1a4827..9cba448a1b 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2577,13 +2577,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 89127ae2767b7d8c2d43560c23fc6068597a1489 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 864d285070..52d608d5e3 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -246,8 +246,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 @@ -264,13 +272,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