All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"Eric Sunshine" <sunshine@sunshineco.com>
Subject: [PATCH v3 0/3] config: allow overriding global/system config
Date: Mon, 12 Apr 2021 16:46:37 +0200	[thread overview]
Message-ID: <cover.1618238567.git.ps@pks.im> (raw)
In-Reply-To: <cover.1617975637.git.ps@pks.im>

[-- Attachment #1: Type: text/plain, Size: 12176 bytes --]

Hi,

this is the third version of my patch series to provide a way of
overriding the global system configuration.

Changes compared to v2:

    - `/dev/null` is now truly special-cased to skip reading any file
      such that it's possible to use it e.g. in environments where this
      special file does not exist.

    - There is no explicit requirement for the given files to exist
      anymore. On the reading side, it will in most cases just be
      ignored (except for e.g. `git config --global --list` and similar,
      where we'd also fail if the normal global config didn't exist). On
      the writing site, we now create the config file it it's missing.

    - Both `git_system_config()` and `git_global_config()` now pass
      memory ownership to the caller.

Patrick

Patrick Steinhardt (3):
  config: rename `git_etc_config()`
  config: unify code paths to get global config paths
  config: allow overriding of global and system configuration

 Documentation/git-config.txt |  5 +++
 Documentation/git.txt        | 10 +++++
 builtin/config.c             | 12 ++++--
 config.c                     | 48 ++++++++++++++++++------
 config.h                     |  4 +-
 t/t1300-config.sh            | 71 ++++++++++++++++++++++++++++++++++++
 6 files changed, 133 insertions(+), 17 deletions(-)

Range-diff against v2:
1:  da0b8ce6f0 ! 1:  34bdbc27d6 config: rename `git_etc_config()`
    @@ Commit message
         would start to become misleading.
     
         Rename the function to `git_system_config()` as a preparatory step.
    +    While at it, the function is also refactored to pass memory ownership to
    +    the caller. This is done to better match semantics of
    +    `git_global_config()`, which is going to be introduced in the next
    +    commit.
     
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
    @@ config.c: static int git_config_from_blob_ref(config_fn_t fn,
      }
      
     -const char *git_etc_gitconfig(void)
    -+const char *git_system_config(void)
    ++char *git_system_config(void)
      {
    - 	static const char *system_wide;
    - 	if (!system_wide)
    +-	static const char *system_wide;
    +-	if (!system_wide)
    +-		system_wide = system_path(ETC_GITCONFIG);
    +-	return system_wide;
    ++	return system_path(ETC_GITCONFIG);
    + }
    + 
    + /*
    +@@ config.c: static int do_git_config_sequence(const struct config_options *opts,
    + 				  config_fn_t fn, void *data)
    + {
    + 	int ret = 0;
    ++	char *system_config = git_system_config();
    + 	char *xdg_config = xdg_config_home("config");
    + 	char *user_config = expand_user_path("~/.gitconfig", 0);
    + 	char *repo_config;
     @@ config.c: 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,
    -+	if (git_config_system() && !access_or_die(git_system_config(), R_OK,
    - 						  opts->system_gently ?
    - 						  ACCESS_EACCES_OK : 0))
    +-						  opts->system_gently ?
    +-						  ACCESS_EACCES_OK : 0))
     -		ret += git_config_from_file(fn, git_etc_gitconfig(),
    -+		ret += git_config_from_file(fn, git_system_config(),
    - 					    data);
    +-					    data);
    ++	if (system_config && !access_or_die(system_config, R_OK,
    ++					    opts->system_gently ?
    ++					    ACCESS_EACCES_OK : 0))
    ++		ret += git_config_from_file(fn, system_config, data);
      
      	current_parsing_scope = CONFIG_SCOPE_GLOBAL;
    + 	if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK))
    +@@ config.c: static int do_git_config_sequence(const struct config_options *opts,
    + 		die(_("unable to parse command-line config"));
    + 
    + 	current_parsing_scope = prev_parsing_scope;
    ++	free(system_config);
    + 	free(xdg_config);
    + 	free(user_config);
    + 	free(repo_config);
     
      ## config.h ##
     @@ config.h: int git_config_rename_section(const char *, const char *);
    @@ config.h: int config_error_nonbool(const char *);
      #define config_error_nonbool(s) (config_error_nonbool(s), const_error())
      #endif
      
    -+const char *git_system_config(void);
    ++char *git_system_config(void);
     +
      int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
      
2:  dddc85bcf5 < -:  ---------- config: unify code paths to get global config paths
-:  ---------- > 2:  30f18679bd config: unify code paths to get global config paths
3:  272a3b31aa ! 3:  af663640ae config: allow overriding of global and system configuration
    @@ Commit message
         and unsetting the first two variables likely has an impact on other
         executables spawned by such a script.
     
    -    The obvious way to fix this would be to introduce `GIT_CONFIG_NOSYSTEM`
    -    as an equivalent to `GIT_CONFIG_NOGLOBAL`. But in the past, it has
    +    The obvious way to fix this would be to introduce `GIT_CONFIG_NOGLOBAL`
    +    as an equivalent to `GIT_CONFIG_NOSYSTEM`. But in the past, it has
         turned out that this design is inflexible: we cannot test system-level
         parsing of the git configuration in our test harness because there is no
         way to change its location, so all tests run with `GIT_CONFIG_NOSYSTEM`
    @@ Commit message
             - If unset, git continues to use the usual locations.
     
             - If set to a specific path, we skip reading the normal
    -          configuration files and instead take the path. This path must
    -          exist and be readable to ensure that the user didn't typo.
    +          configuration files and instead take the path.
     
             - If set to `/dev/null`, we do not load either global- or
               system-level configuration at all.
    @@ Documentation/git.txt: for further details.
     +`GIT_CONFIG_GLOBAL`::
     +`GIT_CONFIG_SYSTEM`::
     +	Take the configuration from the given files instead from global or
    -+	system-level configuration files. The files must exist and be readable
    -+	by the current user. If `GIT_CONFIG_SYSTEM` is set, `/etc/gitconfig`
    ++	system-level configuration files. If `GIT_CONFIG_SYSTEM` is set, the
    ++	system config file defined at build time (usually `/etc/gitconfig`)
     +	will not be read. Likewise, if `GIT_CONFIG_GLOBAL` is set, neither
     +	`$HOME/.gitconfig` nor `$XDG_CONFIG_HOME/git/config` will be read. Can
     +	be set to `/dev/null` to skip reading configuration files of the
    @@ Documentation/git.txt: for further details.
      	Whether to skip reading settings from the system-wide
      	`$(prefix)/etc/gitconfig` file.  This environment variable can
     
    + ## builtin/config.c ##
    +@@ builtin/config.c: int cmd_config(int argc, const char **argv, const char *prefix)
    + 		char *user_config, *xdg_config;
    + 
    + 		git_global_config(&user_config, &xdg_config);
    +-		if (!user_config)
    ++		if (!user_config) {
    ++			if (getenv("GIT_CONFIG_GLOBAL"))
    ++				die(_("GIT_CONFIG_GLOBAL=/dev/null set"));
    ++
    + 			/*
    + 			 * It is unknown if HOME/.gitconfig exists, so
    + 			 * we do not know if we should write to XDG
    +@@ builtin/config.c: int cmd_config(int argc, const char **argv, const char *prefix)
    + 			 * is set and points at a sane location.
    + 			 */
    + 			die(_("$HOME not set"));
    ++		}
    + 
    + 		given_config_source.scope = CONFIG_SCOPE_GLOBAL;
    + 
    +
      ## config.c ##
     @@ config.c: static int git_config_from_blob_ref(config_fn_t fn,
    - const char *git_system_config(void)
    + 
    + char *git_system_config(void)
      {
    - 	static const char *system_wide;
    --	if (!system_wide)
    --		system_wide = system_path(ETC_GITCONFIG);
    -+
    -+	if (!system_wide) {
    -+		system_wide = xstrdup_or_null(getenv("GIT_CONFIG_SYSTEM"));
    -+		if (system_wide) {
    -+			/*
    -+			 * If GIT_CONFIG_SYSTEM is set, it overrides the
    -+			 * /etc/gitconfig. Furthermore, the file must exist in
    -+			 * order to prevent any typos by the user.
    -+			 */
    -+			if (access(system_wide, R_OK))
    -+				die(_("cannot access '%s'"), system_wide);
    -+		} else {
    -+			system_wide = system_path(ETC_GITCONFIG);
    -+		}
    ++	char *system_config = xstrdup_or_null(getenv("GIT_CONFIG_SYSTEM"));
    ++	if (system_config) {
    ++		if (!strcmp(system_config, "/dev/null"))
    ++			FREE_AND_NULL(system_config);
    ++		return system_config;
     +	}
    -+
    - 	return system_wide;
    + 	return system_path(ETC_GITCONFIG);
      }
      
    -@@ config.c: void git_global_config(const char **user, const char **xdg)
    - 	static const char *user_config, *xdg_config;
    +-void git_global_config(char **user_config, char **xdg_config)
    ++void git_global_config(char **user_out, char **xdg_out)
    + {
    +-	*user_config = expand_user_path("~/.gitconfig", 0);
    +-	*xdg_config = xdg_config_home("config");
    ++	char *user_config = xstrdup_or_null(getenv("GIT_CONFIG_GLOBAL"));
    ++	char *xdg_config = NULL;
    ++
    ++	if (user_config) {
    ++		if (!strcmp(user_config, "/dev/null"))
    ++			FREE_AND_NULL(user_config);
    ++		xdg_config = NULL;
    ++	} else {
    ++		user_config = expand_user_path("~/.gitconfig", 0);
    ++		xdg_config = xdg_config_home("config");
    ++	}
    ++
    ++	*user_out = user_config;
    ++	*xdg_out = xdg_config;
    + }
      
    - 	if (!user_config) {
    --		user_config = expand_user_path("~/.gitconfig", 0);
    --		xdg_config = xdg_config_home("config");
    -+		user_config = xstrdup_or_null(getenv("GIT_CONFIG_GLOBAL"));
    -+		if (user_config) {
    -+			/*
    -+			 * If GIT_CONFIG_GLOBAL is set, then it overrides both
    -+			 * the ~/.gitconfig and the XDG configuration file.
    -+			 * Furthermore, the file must exist in order to prevent
    -+			 * any typos by the user.
    -+			 */
    -+			if (access(user_config, R_OK))
    -+				die(_("cannot access '%s'"), user_config);
    -+		} else {
    -+			user_config = expand_user_path("~/.gitconfig", 0);
    -+			xdg_config = xdg_config_home("config");
    -+		}
    - 	}
    - 
    - 	*user = user_config;
    + /*
     
      ## t/t1300-config.sh ##
     @@ t/t1300-config.sh: test_expect_success '--show-scope with --show-origin' '
    @@ t/t1300-config.sh: test_expect_success '--show-scope with --show-origin' '
     +
     +test_expect_success 'override global and system config with missing file' '
     +	sane_unset GIT_CONFIG_NOSYSTEM &&
    -+	test_must_fail env GIT_CONFIG_GLOBAL=does-not-exist git version &&
    -+	test_must_fail env GIT_CONFIG_SYSTEM=does-not-exist git version &&
    -+	GIT_CONFIG_NOSYSTEM=true GIT_CONFIG_SYSTEM=does-not-exist git version
    ++	test_must_fail env GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=/dev/null git config --global --list >actual &&
    ++	test_must_fail env GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=does-not-exist git config --system --list >actual &&
    ++	GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=does-not-exist git version
     +'
     +
     +test_expect_success 'write to overridden global and system config' '
    @@ t/t1300-config.sh: test_expect_success '--show-scope with --show-origin' '
     +	key = value
     +EOF
     +
    -+	test_must_fail env GIT_CONFIG_GLOBAL=write-to-global git config --global config.key value &&
    -+	touch write-to-global &&
     +	GIT_CONFIG_GLOBAL=write-to-global git config --global config.key value &&
     +	test_cmp expect write-to-global &&
     +
    -+	test_must_fail env GIT_CONFIG_SYSTEM=write-to-system git config --system config.key value &&
    -+	touch write-to-system &&
     +	GIT_CONFIG_SYSTEM=write-to-system git config --system config.key value &&
     +	test_cmp expect write-to-system
     +'
-- 
2.31.1


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2021-04-12 14:46 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-08 14:17 [PATCH] config: Introduce GIT_CONFIG_NOGLOBAL Patrick Steinhardt
2021-04-08 16:44 ` Eric Sunshine
2021-04-08 17:25 ` Junio C Hamano
2021-04-08 23:18   ` Jeff King
2021-04-08 23:43     ` Junio C Hamano
2021-04-09  0:25       ` Jeff King
2021-04-08 23:34   ` Ævar Arnfjörð Bjarmason
2021-04-08 23:39   ` Ævar Arnfjörð Bjarmason
2021-04-08 23:30 ` Ævar Arnfjörð Bjarmason
2021-04-08 23:56   ` Junio C Hamano
2021-04-09 13:43 ` [PATCH v2 0/3] config: allow overriding global/system config Patrick Steinhardt
2021-04-09 13:43   ` [PATCH v2 1/3] config: rename `git_etc_config()` Patrick Steinhardt
2021-04-09 15:13     ` Jeff King
2021-04-09 13:43   ` [PATCH v2 2/3] config: unify code paths to get global config paths Patrick Steinhardt
2021-04-09 15:21     ` Jeff King
2021-04-09 13:43   ` [PATCH v2 3/3] config: allow overriding of global and system configuration Patrick Steinhardt
2021-04-09 15:38     ` Jeff King
2021-04-12 14:04       ` Patrick Steinhardt
2021-04-09 22:18     ` Junio C Hamano
2021-04-09 15:41   ` [PATCH v2 0/3] config: allow overriding global/system config Jeff King
2021-04-12 14:46   ` Patrick Steinhardt [this message]
2021-04-12 14:46     ` [PATCH v3 1/3] config: rename `git_etc_config()` Patrick Steinhardt
2021-04-12 14:46     ` [PATCH v3 2/3] config: unify code paths to get global config paths Patrick Steinhardt
2021-04-12 14:46     ` [PATCH v3 3/3] config: allow overriding of global and system configuration Patrick Steinhardt
2021-04-12 17:04       ` Junio C Hamano
2021-04-13  7:11     ` [PATCH v4 0/3] config: allow overriding global/system config Patrick Steinhardt
2021-04-13  7:11       ` [PATCH v4 1/3] config: rename `git_etc_config()` Patrick Steinhardt
2021-04-13  7:25         ` Jeff King
2021-04-16 21:14         ` SZEDER Gábor
2021-04-17  8:44           ` Jeff King
2021-04-17 21:37             ` Junio C Hamano
2021-04-18  5:39               ` Jeff King
2021-04-19 11:03                 ` Patrick Steinhardt
2021-04-23  9:27                   ` Jeff King
2021-04-13  7:11       ` [PATCH v4 2/3] config: unify code paths to get global config paths Patrick Steinhardt
2021-04-13  7:11       ` [PATCH v4 3/3] config: allow overriding of global and system configuration Patrick Steinhardt
2021-04-13  7:33         ` Jeff King
2021-04-13  7:54           ` Patrick Steinhardt
2021-04-13  7:33       ` [PATCH v4 0/3] config: allow overriding global/system config Jeff King
2021-04-13 17:49       ` Junio C Hamano
2021-04-14  5:37         ` Patrick Steinhardt
2021-04-19 12:31       ` [PATCH v5 " Patrick Steinhardt
2021-04-19 12:31         ` [PATCH v5 1/3] config: rename `git_etc_config()` Patrick Steinhardt
2021-04-19 12:31         ` [PATCH v5 2/3] config: unify code paths to get global config paths Patrick Steinhardt
2021-04-19 12:31         ` [PATCH v5 3/3] config: allow overriding of global and system configuration Patrick Steinhardt
2021-04-21 20:46           ` SZEDER Gábor
2021-04-21 21:06             ` SZEDER Gábor
2021-04-22  5:36               ` Patrick Steinhardt
2021-04-23  5:47             ` [PATCH] t1300: fix unset of GIT_CONFIG_NOSYSTEM leaking into subsequent tests Patrick Steinhardt
2021-04-19 21:55         ` [PATCH v5 0/3] config: allow overriding global/system config Junio C Hamano
2021-04-23  9:32         ` Jeff King
2021-04-12 14:46 ` [PATCH v3] config: allow overriding of global and system configuration Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover.1618238567.git.ps@pks.im \
    --to=ps@pks.im \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.