git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Jonathan Niedier <jrnieder@gmail.com>,
	Junio C Hamano <gitster@pobox.com>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 41/42] setup: rework setup_explicit_git_dir()
Date: Fri, 29 Oct 2010 13:48:53 +0700	[thread overview]
Message-ID: <1288334934-17216-42-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1288334934-17216-1-git-send-email-pclouds@gmail.com>

This function is the most complex one among the three setup_*
functions because all GIT_DIR, GIT_WORK_TREE, core.worktree and
core.bare are involved.

Because core.worktree is only effective inside
setup_explicit_git_dir() and the extra code in setup_git_directory()
is to handle that. The extra code can now be retired.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 setup.c |  135 ++++++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 78 insertions(+), 57 deletions(-)

diff --git a/setup.c b/setup.c
index dc91e0a..ba2a90e 100644
--- a/setup.c
+++ b/setup.c
@@ -208,24 +208,6 @@ int is_inside_work_tree(void)
 	return inside_work_tree;
 }
 
-/*
- * set_work_tree() is only ever called if you set GIT_DIR explicitly.
- * The old behaviour (which we retain here) is to set the work tree root
- * to the cwd, unless overridden by the config, the command line, or
- * GIT_WORK_TREE.
- */
-static const char *set_work_tree(const char *dir)
-{
-	char buffer[PATH_MAX + 1];
-
-	if (!getcwd(buffer, sizeof(buffer)))
-		die ("Could not get the current working directory");
-	git_work_tree_cfg = xstrdup(buffer);
-	inside_work_tree = 1;
-
-	return NULL;
-}
-
 void setup_work_tree(void)
 {
 	const char *work_tree, *git_dir;
@@ -326,38 +308,92 @@ const char *read_gitfile_gently(const char *path)
 }
 
 static const char *setup_explicit_git_dir(const char *gitdirenv,
-				const char *work_tree_env, int *nongit_ok)
+					  char *cwd, int len,
+					  int *nongit_ok)
 {
-	static char buffer[1024 + 1];
-	const char *retval;
+	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
+	const char *worktree;
+	char *gitfile;
 
 	if (PATH_MAX - 40 < strlen(gitdirenv))
 		die("'$%s' too big", GIT_DIR_ENVIRONMENT);
+
+	gitfile = (char*)read_gitfile_gently(gitdirenv);
+	if (gitfile) {
+		gitfile = xstrdup(gitfile);
+		gitdirenv = gitfile;
+	}
+
 	if (!is_git_directory(gitdirenv)) {
 		if (nongit_ok) {
 			*nongit_ok = 1;
+			free(gitfile);
 			return NULL;
 		}
 		die("Not a git repository: '%s'", gitdirenv);
 	}
-	if (!work_tree_env) {
-		retval = set_work_tree(gitdirenv);
-		/* config may override worktree */
-		if (check_repository_format_gently(gitdirenv, nongit_ok))
-			return NULL;
-		return retval;
+
+	if (check_repository_format_gently(gitdirenv, nongit_ok)) {
+		free(gitfile);
+		return NULL;
 	}
-	if (check_repository_format_gently(gitdirenv, nongit_ok))
+
+	/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */
+	if (work_tree_env)
+		set_git_work_tree(work_tree_env);
+	else if (is_bare_repository_cfg > 0) {
+		if (git_work_tree_cfg) /* #22.2, #30 */
+			die("core.bare and core.worktree do not make sense");
+
+		/* #18, #26 */
+		set_git_dir(gitdirenv);
+		free(gitfile);
 		return NULL;
-	retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
-			get_git_work_tree());
-	if (!retval || !*retval)
+	}
+	else if (git_work_tree_cfg) { /* #6, #14 */
+		if (is_absolute_path(git_work_tree_cfg))
+			set_git_work_tree(git_work_tree_cfg);
+		else {
+			char core_worktree[PATH_MAX];
+			if (chdir(gitdirenv))
+				die_errno("Could not chdir to '%s'", gitdirenv);
+			if (chdir(git_work_tree_cfg))
+				die_errno("Could not chdir to '%s'", git_work_tree_cfg);
+			if (!getcwd(core_worktree, PATH_MAX))
+				die_errno("Could not get directory '%s'", git_work_tree_cfg);
+			if (chdir(cwd))
+				die_errno("Could not come back to cwd");
+			set_git_work_tree(core_worktree);
+		}
+	}
+	else /* #2, #10 */
+		set_git_work_tree(".");
+
+	/* set_git_work_tree() must have been called by now */
+	worktree = get_git_work_tree();
+
+	/* both get_git_work_tree() and cwd are already normalized */
+	if (!strcmp(cwd, worktree)) { /* cwd == worktree */
+		set_git_dir(gitdirenv);
+		free(gitfile);
 		return NULL;
-	set_git_dir(make_absolute_path(gitdirenv));
-	if (chdir(work_tree_env) < 0)
-		die_errno ("Could not chdir to '%s'", work_tree_env);
-	strcat(buffer, "/");
-	return retval;
+	}
+
+	if (!prefixcmp(cwd, worktree) &&
+	    cwd[strlen(worktree)] == '/') { /* cwd inside worktree */
+		set_git_dir(make_absolute_path(gitdirenv));
+		if (chdir(worktree))
+			die_errno("Could not chdir to '%s'", worktree);
+		cwd[len++] = '/';
+		cwd[len] = '\0';
+		free(gitfile);
+		return cwd + strlen(worktree) + 1;
+	}
+
+	/* cwd outside worktree */
+	set_git_dir(gitdirenv);
+	free(gitfile);
+	return NULL;
 }
 
 static const char *setup_discovered_git_dir(const char *gitdir,
@@ -442,7 +478,6 @@ static dev_t get_device_or_die(const char *path, const char *prefix)
  */
 static const char *setup_git_directory_gently_1(int *nongit_ok)
 {
-	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
 	const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
 	static char cwd[PATH_MAX+1];
 	const char *gitdirenv, *ret;
@@ -459,6 +494,10 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	if (nongit_ok)
 		*nongit_ok = 0;
 
+	if (!getcwd(cwd, sizeof(cwd)-1))
+		die_errno("Unable to read current working directory");
+	offset = len = strlen(cwd);
+
 	/*
 	 * If GIT_DIR is set explicitly, we're not going
 	 * to do any discovery, but we still do repository
@@ -466,10 +505,7 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	 */
 	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
 	if (gitdirenv)
-		return setup_explicit_git_dir(gitdirenv, work_tree_env, nongit_ok);
-
-	if (!getcwd(cwd, sizeof(cwd)-1))
-		die_errno("Unable to read current working directory");
+		return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok);
 
 	ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
 	if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
@@ -486,7 +522,6 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	 * - ../../.git/
 	 *   etc.
 	 */
-	offset = len = strlen(cwd);
 	one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
 	if (one_filesystem)
 		current_device = get_device_or_die(".", NULL);
@@ -629,19 +664,5 @@ int check_repository_format(void)
  */
 const char *setup_git_directory(void)
 {
-	const char *retval = setup_git_directory_gently(NULL);
-
-	/* If the work tree is not the default one, recompute prefix */
-	if (inside_work_tree < 0) {
-		static char buffer[PATH_MAX + 1];
-		char *rel;
-		if (retval && chdir(retval))
-			die_errno ("Could not jump back into original cwd");
-		rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
-		if (rel && *rel && chdir(get_git_work_tree()))
-			die_errno ("Could not jump to working directory");
-		return rel && *rel ? strcat(rel, "/") : NULL;
-	}
-
-	return retval;
+	return setup_git_directory_gently(NULL);
 }
-- 
1.7.0.2.445.gcbdb3

  parent reply	other threads:[~2010-10-29  6:54 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-29  6:48 [PATCH 00/42] repo setup test cases and fixes Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 01/42] builtins: print setup info if repo is found Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 02/42] Add t1510 and basic rules that run repo setup Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 03/42] t1510: setup case #0 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 04/42] t1510: setup case #1 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 05/42] t1510: setup case #2 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 06/42] t1510: setup case #3 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 07/42] t1510: setup case #4 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 08/42] t1510: setup case #5 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 09/42] t1510: setup case #6 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 10/42] t1510: setup case #7 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 11/42] t1510: setup case #8 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 12/42] t1510: setup case #9 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 13/42] t1510: setup case #10 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 14/42] t1510: setup case #11 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 15/42] t1510: setup case #12 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 16/42] t1510: setup case #13 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 17/42] t1510: setup case #14 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 18/42] t1510: setup case #15 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 19/42] t1510: setup case #16 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 20/42] t1510: setup case #17 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 21/42] t1510: setup case #18 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 22/42] t1510: setup case #19 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 23/42] t1510: setup case #20 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 24/42] t1510: setup case #21 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 25/42] t1510: setup case #22 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 26/42] t1510: setup case #23 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 27/42] t1510: setup case #24 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 28/42] t1510: setup case #25 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 29/42] t1510: setup case #26 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 30/42] t1510: setup case #27 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 31/42] t1510: setup case #28 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 32/42] t1510: setup case #29 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 33/42] t1510: setup case #30 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 34/42] t1510: setup case #31 Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 35/42] rev-parse: prints --git-dir relative to user's cwd Nguyễn Thái Ngọc Duy
2010-10-29 17:06   ` Sverre Rabbelier
2010-10-30  4:42     ` Nguyen Thai Ngoc Duy
2010-10-30  7:09       ` Jonathan Nieder
2010-10-29  6:48 ` [PATCH 36/42] Add git_config_early() Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 37/42] Use git_config_early() instead of git_config() during repo setup Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 38/42] Remove all logic from get_git_work_tree() Nguyễn Thái Ngọc Duy
2010-10-29 17:09   ` Sverre Rabbelier
2010-10-30  4:38     ` Nguyen Thai Ngoc Duy
2010-11-01  6:26     ` [PATCH 1/9] git-rev-parse.txt: clarify --git-dir Nguyễn Thái Ngọc Duy
2010-11-01  6:26     ` [PATCH 2/9] rev-parse: prints --git-dir relative to user's cwd Nguyễn Thái Ngọc Duy
2010-11-01  6:26     ` [PATCH 3/9] Add git_config_early() Nguyễn Thái Ngọc Duy
2010-11-01  6:26     ` [PATCH 4/9] Use git_config_early() instead of git_config() during repo setup Nguyễn Thái Ngọc Duy
2010-11-01  6:26     ` [PATCH 5/9] setup: limit get_git_work_tree()'s to explicit setup case only Nguyễn Thái Ngọc Duy
2010-11-01  6:26     ` [PATCH 6/9] setup: clean up setup_bare_git_dir() Nguyễn Thái Ngọc Duy
2010-11-01  6:26     ` [PATCH 7/9] setup: clean up setup_discovered_git_dir() Nguyễn Thái Ngọc Duy
2010-11-01  6:26     ` [PATCH 8/9] setup: rework setup_explicit_git_dir() Nguyễn Thái Ngọc Duy
2010-11-01  6:26     ` [PATCH 9/9] Remove all logic from get_git_work_tree() Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 39/42] setup: clean up setup_bare_git_dir() Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` [PATCH 40/42] setup: clean up setup_discovered_git_dir() Nguyễn Thái Ngọc Duy
2010-10-29  6:48 ` Nguyễn Thái Ngọc Duy [this message]
2010-10-29  6:48 ` [PATCH 42/42] t1510: all failed tests are now fixed Nguyễn Thái Ngọc Duy
2010-10-29  8:29   ` Nguyen Thai Ngoc Duy
2010-10-29 17:04 ` [PATCH 00/42] repo setup test cases and fixes Sverre Rabbelier
2010-10-29 17:09   ` Jonathan Nieder

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=1288334934-17216-42-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jrnieder@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).