From 9eb22340010a2855cbc04441ce4fb03d055c6297 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 b28004b383..5d847f12b0 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 8e240435be..4e4021a93e 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 32ae421d07..62a79b18b7 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2605,3 +2605,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 221de4bc0f..09949b7580 100644 --- a/config.c +++ b/config.c @@ -1672,9 +1672,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 585db37c86..548d938fab 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 89d71b4937ae42df49b42731cd1368454fcee8a4 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 4e4021a93e..a3a859ef8f 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 0fd5b7c23eb04648315d8df9e6e18ab55fb17566 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 a3a859ef8f..5fd9b865b8 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 62a79b18b7..06b9b46a07 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2613,13 +2613,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 c8ea5159e50ccc52dd207eb0168fa25576d2f5d4 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 5fd9b865b8..3ca1dd7c60 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