git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[WIP PATCH 04/26] Add GIT_HARDENED_SETUP to detect gitdir/worktree related mis-setup errors

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 16, 2010, 16:04 UTC
Message-ID
<1266336317-607-5-git-send-email-pclouds@gmail.com>
In-Reply-To
<1266336317-607-1-git-send-email-pclouds@gmail.com>

When GIT_DIR environment variable is not specified, .git will be searched if a repository is needed. Currently this can be done in two places: setup_git_directory_gently() and setup_git_env().

The one in setup_git_env() is no longer correct and should IMHO have been removed since the introduction of setup_git_directory_gently() in d288a70. Having two ways of auto detection may lead to obscure errors because .git may be misdetected by setup_git_env(), automatically called via git_path(), which is all over the place.

This patch makes setup_git_env() die if GIT_DIR is not explictly set. That's setup_git_directory_gently()'s job. If you ever want to touch things inside $GIT_DIR, you should have already called setup_git_directory_gently().

However, doing that will break Git the hard way. So the die()ing behavior will be only triggered if environment variable GIT_HARDENED_SETUP is set. Otherwise old behavior remains. Once all Git commands have been adapted to stay away from the old behavior, the old code can be removed.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 config.c      |   17 ++++++++++++-----
 environment.c |   42 ++++++++++++++++++++++++++++++++----------
 setup.c       |    4 +++-
 3 files changed, 47 insertions(+), 16 deletions(-)
diff --git a/config.c b/config.c
index 6963fbe..eee12b4 100644
--- a/config.c
+++ b/config.c
@@ -704,6 +704,7 @@ int git_config(config_fn_t fn, void *data)
 	int ret = 0, found = 0;
 	char *repo_config = NULL;
 	const char *home = NULL;
+	const char *hardened_setup = getenv("GIT_HARDENED_SETUP");
 
 	/* Setting $GIT_CONFIG makes git read _only_ the given config file. */
 	if (config_exclusive_filename)
@@ -724,12 +725,18 @@ int git_config(config_fn_t fn, void *data)
 		free(user_config);
 	}
 
-	repo_config = git_pathdup("config");
-	if (!access(repo_config, R_OK)) {
-		ret += git_config_from_file(fn, repo_config, data);
-		found += 1;
+	if (hardened_setup && !*hardened_setup)
+		hardened_setup = NULL;
+	if (hardened_setup && startup_info && !startup_info->have_set_gitdir)
+		die("Try to access a repository before properly setting it up");
+	if (!hardened_setup || !startup_info || startup_info->have_repository) {
+		repo_config = git_pathdup("config");
+		if (!access(repo_config, R_OK)) {
+			ret += git_config_from_file(fn, repo_config, data);
+			found += 1;
+		}
+		free(repo_config);
 	}
-	free(repo_config);
 	if (found == 0)
 		return -1;
 	return ret;
diff --git a/environment.c b/environment.c
index 1ab8815..4795441 100644
--- a/environment.c
+++ b/environment.c
@@ -66,9 +66,19 @@ static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
 
 static void setup_git_env(void)
 {
+	const char *harden_setup = getenv("GIT_HARDENED_SETUP");
+
+	if (harden_setup && !*harden_setup)
+		harden_setup = NULL;
+
 	git_dir = getenv(GIT_DIR_ENVIRONMENT);
-	if (!git_dir)
-		git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+	if (!git_dir) {
+		if (harden_setup)
+			die("GIT_DIR not properly set");
+		 git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+	}
+	if (harden_setup && startup_info && startup_info->have_set_gitdir)
+			die("internal error: setup_git_env can't be called twice");
 	if (!git_dir)
 		git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
 	git_object_dir = getenv(DB_ENVIRONMENT);
@@ -103,8 +113,11 @@ int have_git_dir(void)
 
 const char *get_git_dir(void)
 {
-	if (!git_dir)
-		setup_git_env();
+	if (!git_dir) {
+		const char *harden_setup = getenv("GIT_HARDENED_SETUP");
+		if (!harden_setup || !*harden_setup)
+			setup_git_env();
+	}
 	return git_dir;
 }
 
@@ -146,22 +159,31 @@ const char *get_git_work_tree(void)
 
 char *get_object_directory(void)
 {
-	if (!git_object_dir)
-		setup_git_env();
+	if (!git_object_dir) {
+		const char *harden_setup = getenv("GIT_HARDENED_SETUP");
+		if (!harden_setup || !*harden_setup)
+			setup_git_env();
+	}
 	return git_object_dir;
 }
 
 char *get_index_file(void)
 {
-	if (!git_index_file)
-		setup_git_env();
+	if (!git_index_file) {
+		const char *harden_setup = getenv("GIT_HARDENED_SETUP");
+		if (!harden_setup || !*harden_setup)
+			setup_git_env();
+	}
 	return git_index_file;
 }
 
 char *get_graft_file(void)
 {
-	if (!git_graft_file)
-		setup_git_env();
+	if (!git_graft_file) {
+		const char *harden_setup = getenv("GIT_HARDENED_SETUP");
+		if (!harden_setup || !*harden_setup)
+			setup_git_env();
+	}
 	return git_graft_file;
 }
 
diff --git a/setup.c b/setup.c
index 0c05d36..5c8777a 100644
--- a/setup.c
+++ b/setup.c
@@ -453,8 +453,10 @@ const char *setup_git_directory_gently(int *nongit_ok)
 	const char *prefix;
 
 	prefix = setup_git_directory_gently_1(nongit_ok);
-	if (startup_info)
+	if (startup_info) {
 		startup_info->have_set_gitdir = 1;
+		startup_info->have_repository = get_git_dir() != NULL;
+	}
 	if ((!nongit_ok || !*nongit_ok) && check_repository_format_gently(nongit_ok))
 		prefix = NULL;
 	if (startup_info) {
-- 
1.7.0.195.g637a2
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 5 of 27 in “Git setup cleanup series”
  1. 00/26 Git setup cleanup seriesNguyễn Thái Ngọc Duy, Feb 16, 2010
  2. 01/26 rev-parse --git-dir: print relative gitdir correctlyNguyễn Thái Ngọc Duy, Feb 16, 2010
  3. 02/26 setup_git_directory*: Explicitly set git dirNguyễn Thái Ngọc Duy, Feb 16, 2010
  4. 03/26 Save setup_git_dir* info globally for later useNguyễn Thái Ngọc Duy, Feb 16, 2010
  5. 04/26 Add GIT_HARDENED_SETUP to detect gitdir/worktree related mis-setup errorsNguyễn Thái Ngọc Duy, Feb 16, 2010
  6. 05/26 enter_repo(): use setup_git_directory_gently internallyNguyễn Thái Ngọc Duy, Feb 16, 2010
  7. 06/26 Tweak init/clone to work properly with GIT_HARDENED_SETUP=1Nguyễn Thái Ngọc Duy, Feb 16, 2010
  8. 07/26 Support running setup_git_dir_gently() from the beginning for builtin commandsNguyễn Thái Ngọc Duy, Feb 16, 2010
  9. 08/26 config: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  10. 09/26 hash-object: move gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  11. 10/26 shortlog: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  12. 11/26 Do not look for .git/info/exclude when gitdir is not set upNguyễn Thái Ngọc Duy, Feb 16, 2010
  13. 12/26 grep: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  14. 13/26 USE_PAGER should not be used without RUN_SETUP*Nguyễn Thái Ngọc Duy, Feb 16, 2010
  15. 14/26 Do not try to read $GIT_DIR/info/attributes if there is no repositoryNguyễn Thái Ngọc Duy, Feb 16, 2010
  16. 15/26 archive: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  17. 16/26 mailinfo: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  18. 17/26 check-ref-format: setup gitdir gentlyNguyễn Thái Ngọc Duy, Feb 16, 2010
  19. 18/26 verify-pack: set up gitdir gentlyNguyễn Thái Ngọc Duy, Feb 16, 2010
  20. 19/26 apply: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  21. 20/26 bundle: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  22. 21/26 diff: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  23. 22/26 help: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  24. 23/26 ls-remote: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  25. 24/26 var: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  26. 25/26 merge-file: move up gitdir setup to run_builtin()Nguyễn Thái Ngọc Duy, Feb 16, 2010
  27. 26/26 Turn on GIT_HARDENED_SETUP for the whole test suiteNguyễn Thái Ngọc Duy, Feb 16, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.