From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Subject: [PATCH 43/47] setup: rework setup_explicit_git_dir() Date: Fri, 26 Nov 2010 22:32:39 +0700 Message-ID: <1290785563-15339-44-git-send-email-pclouds@gmail.com> References: <1290785563-15339-1-git-send-email-pclouds@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= , Junio C Hamano To: git@vger.kernel.org, Junio C Hamano X-From: git-owner@vger.kernel.org Fri Nov 26 17:05:47 2010 Return-path: Envelope-to: gcvg-git-2@lo.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PM0nx-00049l-Ta for gcvg-git-2@lo.gmane.org; Fri, 26 Nov 2010 17:05:46 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755078Ab0KZQFk convert rfc822-to-quoted-printable (ORCPT ); Fri, 26 Nov 2010 11:05:40 -0500 Received: from mail-pz0-f66.google.com ([209.85.210.66]:43248 "EHLO mail-pz0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753895Ab0KZQFj (ORCPT ); Fri, 26 Nov 2010 11:05:39 -0500 Received: by pzk26 with SMTP id 26so460814pzk.1 for ; Fri, 26 Nov 2010 08:05:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:received:from:to:cc:subject :date:message-id:x-mailer:in-reply-to:references:mime-version :content-type:content-transfer-encoding; bh=BmsZKYT5RgzXg9BW6FzOElUiWNjuJyB4tFz4SVfP4F0=; b=CyMNdGgT+r3cE8nwTUmmconQP9mChzgUuQKz9AX9CSK3A3dQQ8OK5mykGF6O6+cjVT gNnNz73q22P5YyUd3ECW6sF08B/grnAt9UC5SN4i6oB5bkx6WPYEliFvCieXgup2mWhv eKoz2XP8rU7pNbRDjqFWYOlOG740HC72YHjw4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :mime-version:content-type:content-transfer-encoding; b=t7fbJrbD+TVFx7z6xhTpryemUUzXilOD4cXvKaAyZ5WeU8hCnqQ4DW0zqHoT8MSUPq SIZLlVvA8auG75EGadBweeiXp9yG8JSL3EAkQZPLTFZmqMIyxDyNfm6wMk1zdwrKrH9g mbsm5HzduLUeiq7VuiMiIgv0+iqxvT+RQoAr0= Received: by 10.142.51.14 with SMTP id y14mr2522728wfy.306.1290786629897; Fri, 26 Nov 2010 07:50:29 -0800 (PST) Received: from pclouds@gmail.com ([115.73.252.168]) by mx.google.com with ESMTPS id w22sm2687914wfd.7.2010.11.26.07.50.17 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 26 Nov 2010 07:50:28 -0800 (PST) Received: by pclouds@gmail.com (sSMTP sendmail emulation); Fri, 26 Nov 2010 22:49:07 +0700 X-Mailer: git-send-email 1.7.3.2.316.gda8b3 In-Reply-To: <1290785563-15339-1-git-send-email-pclouds@gmail.com> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: 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. Also note that setup_explicit assignment is removed, worktree setting is no longer decided by get_git_work_tree(). get_git_work_tree() will be simplified in the next commit. Signed-off-by: Nguy=E1=BB=85n Th=C3=A1i Ng=E1=BB=8Dc Duy Signed-off-by: Junio C Hamano --- setup.c | 138 +++++++++++++---------- t/t1510-repo-setup.sh | 286 ++++++++++++++++++++++++-----------------= ------- 2 files changed, 221 insertions(+), 203 deletions(-) diff --git a/setup.c b/setup.c index 3ee9c2e..2e2865c 100644 --- a/setup.c +++ b/setup.c @@ -208,24 +208,6 @@ int is_inside_work_tree(void) return inside_work_tree; } =20 -/* - * 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 ro= ot - * 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 =3D xstrdup(buffer); - inside_work_tree =3D 1; - - return NULL; -} - void setup_work_tree(void) { const char *work_tree, *git_dir; @@ -326,40 +308,92 @@ const char *read_gitfile_gently(const char *path) } =20 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 =3D getenv(GIT_WORK_TREE_ENVIRONMENT); + const char *worktree; + char *gitfile; =20 - if (startup_info) - startup_info->setup_explicit =3D 1; if (PATH_MAX - 40 < strlen(gitdirenv)) die("'$%s' too big", GIT_DIR_ENVIRONMENT); + + gitfile =3D (char*)read_gitfile_gently(gitdirenv); + if (gitfile) { + gitfile =3D xstrdup(gitfile); + gitdirenv =3D gitfile; + } + if (!is_git_directory(gitdirenv)) { if (nongit_ok) { *nongit_ok =3D 1; + free(gitfile); return NULL; } die("Not a git repository: '%s'", gitdirenv); } - if (!work_tree_env) { - retval =3D 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 =3D 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 =3D get_git_work_tree(); + + /* both get_git_work_tree() and cwd are already normalized */ + if (!strcmp(cwd, worktree)) { /* cwd =3D=3D 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)] =3D=3D '/') { /* cwd inside worktree */ + set_git_dir(make_absolute_path(gitdirenv)); + if (chdir(worktree)) + die_errno("Could not chdir to '%s'", worktree); + cwd[len++] =3D '/'; + cwd[len] =3D '\0'; + free(gitfile); + return cwd + strlen(worktree) + 1; + } + + /* cwd outside worktree */ + set_git_dir(gitdirenv); + free(gitfile); + return NULL; } =20 static const char *setup_discovered_git_dir(const char *gitdir, @@ -441,7 +475,6 @@ static dev_t get_device_or_die(const char *path, co= nst char *prefix) */ static const char *setup_git_directory_gently_1(int *nongit_ok) { - const char *work_tree_env =3D getenv(GIT_WORK_TREE_ENVIRONMENT); const char *env_ceiling_dirs =3D getenv(CEILING_DIRECTORIES_ENVIRONME= NT); static char cwd[PATH_MAX+1]; const char *gitdirenv, *ret; @@ -458,6 +491,10 @@ static const char *setup_git_directory_gently_1(in= t *nongit_ok) if (nongit_ok) *nongit_ok =3D 0; =20 + if (!getcwd(cwd, sizeof(cwd)-1)) + die_errno("Unable to read current working directory"); + offset =3D len =3D strlen(cwd); + /* * If GIT_DIR is set explicitly, we're not going * to do any discovery, but we still do repository @@ -465,10 +502,7 @@ static const char *setup_git_directory_gently_1(in= t *nongit_ok) */ gitdirenv =3D 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); =20 ceil_offset =3D longest_ancestor_length(cwd, env_ceiling_dirs); if (ceil_offset < 0 && has_dos_drive_prefix(cwd)) @@ -485,7 +519,6 @@ static const char *setup_git_directory_gently_1(int= *nongit_ok) * - ../../.git/ * etc. */ - offset =3D len =3D strlen(cwd); one_filesystem =3D !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0= ); if (one_filesystem) current_device =3D get_device_or_die(".", NULL); @@ -628,20 +661,5 @@ int check_repository_format(void) */ const char *setup_git_directory(void) { - const char *retval =3D setup_git_directory_gently(NULL); - - /* If the work tree is not the default one, recompute prefix */ - if ((!startup_info || startup_info->setup_explicit) && - 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 =3D 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); } diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh index 5ae02ee..b7e4d5d 100755 --- a/t/t1510-repo-setup.sh +++ b/t/t1510-repo-setup.sh @@ -651,7 +651,7 @@ EOF test_repo 6 "$TRASH_DIRECTORY/6/.git" ' =20 -test_expect_failure '#6: GIT_DIR(rel), core.worktree=3D.. in subdir' ' +test_expect_success '#6: GIT_DIR(rel), core.worktree=3D.. in subdir' ' cat >6/sub/sub/expected <6/sub/sub/expected <6/expected <6/sub/sub/expected <6/sub/sub/expected <10/expected <10/sub/expected <10/expected <10/sub/expected <11/expected <11/expected <11/sub/sub/expected <11/sub/expected <11/expected <11/expected <11/expected <11/expected <11/sub/sub/expected <11/sub/sub/expected <11/expected <11/expected <11/expected <11/expected <11/sub/sub/expected <11/sub/sub/expected <14/expected <14/expected <14/sub/sub/expected <14/sub/sub/expected <14/sub/expected <14/sub/sub/expected <14/expected <14/expected <14/expected <14/expected <14/sub/sub/expected <14/sub/sub/expected <14/sub/sub/expected <14/expected <14/expected <14/expected <14/expected <14/sub/sub/expected <14/sub/sub/expected <15/expected <15/expected <15/sub/sub/expected <15/sub/expected <15/expected <15/expected <15/expected <15/expected <15/sub/sub/expected <15/sub/sub/expected <15/expected <15/expected <15/expected <15/expected <15/sub/sub/expected <15/sub/sub/expected <22/.git/sub/expected <22/.git/sub/expected <22/.git/expected <22/.git/sub/expected <22/.git/sub/expected <26/expected <26/expected <26/sub/expected <26/sub/expected <27/expected <27/expected <27/sub/sub/expected <27/sub/expected <27/expected <27/expected <27/expected <27/expected <27/sub/sub/expected <27/sub/sub/expected <27/expected <27/expected <27/expected <27/expected <27/sub/sub/expected <27/sub/sub/expected <31/expected <31/expected <31/sub/sub/expected <31/sub/expected <31/expected <31/expected <31/expected <31/expected <31/sub/sub/expected <31/sub/sub/expected <31/expected <31/expected <31/expected <31/expected <31/sub/sub/expected <31/sub/sub/expected <