From: Clemens Buchacher <drizzd@aon.at>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Frédéric Brière" <fbriere@fbriere.net>,
"Jonathan Nieder" <jrnieder@gmail.com>
Subject: [PATCH] setup: do not change to work tree prematurely
Date: Sun, 23 May 2010 02:07:19 +0200 [thread overview]
Message-ID: <20100523000719.GA32380@localhost> (raw)
If the work tree is known and a git command is invoked from within
a git directory, git_setup_directory() will try to find the
relative path from the work tree to the git dir. After doing so it
changes directories to the work tree. It fails to update the
relative path to the git directory, however.
Instead, do not change the working directory at this point and wait
for git_setup_work_tree() to handle this correctly.
This fixes the following bug.
$ cd .git
$ git --work-tree=/tmp/git symbolic-ref HEAD
fatal: ref HEAD is not a symbolic ref
Reported-by: Frédéric Brière <fbriere@fbriere.net>
Signed-off-by: Clemens Buchacher <drizzd@aon.at>
---
I am not 100% certain that my analysis is correct, since I still do
not understand the setup code. But as far as setup_git_directory()
is concerned, I think this is the intended behavior.
Clemens
dir.c | 33 +++++++++++++++++++--------------
dir.h | 1 +
setup.c | 14 +++++++++-----
3 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/dir.c b/dir.c
index cb83332..7bf208d 100644
--- a/dir.c
+++ b/dir.c
@@ -926,6 +926,24 @@ int file_exists(const char *f)
return lstat(f, &sb) == 0;
}
+char *get_relative_path(char *cwd, const char *dir)
+{
+ if (!dir)
+ return NULL;
+ if (!is_absolute_path(dir))
+ dir = make_absolute_path(dir);
+
+ while (*dir && *dir == *cwd) {
+ dir++;
+ cwd++;
+ }
+ if (*dir)
+ return NULL;
+ if (*cwd == '/')
+ return cwd + 1;
+ return cwd;
+}
+
/*
* get_relative_cwd() gets the prefix of the current working directory
* relative to 'dir'. If we are not inside 'dir', it returns NULL.
@@ -942,25 +960,12 @@ int file_exists(const char *f)
*/
char *get_relative_cwd(char *buffer, int size, const char *dir)
{
- char *cwd = buffer;
-
if (!dir)
return NULL;
if (!getcwd(buffer, size))
die_errno("can't find the current directory");
- if (!is_absolute_path(dir))
- dir = make_absolute_path(dir);
-
- while (*dir && *dir == *cwd) {
- dir++;
- cwd++;
- }
- if (*dir)
- return NULL;
- if (*cwd == '/')
- return cwd + 1;
- return cwd;
+ return get_relative_path(buffer, dir);
}
int is_inside_dir(const char *dir)
diff --git a/dir.h b/dir.h
index 3bead5f..3bcda1f 100644
--- a/dir.h
+++ b/dir.h
@@ -79,6 +79,7 @@ extern void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *which);
extern int file_exists(const char *);
+extern char *get_relative_path(char *cwd, const char *dir);
extern char *get_relative_cwd(char *buffer, int size, const char *dir);
extern int is_inside_dir(const char *dir);
diff --git a/setup.c b/setup.c
index 5716d90..67b5122 100644
--- a/setup.c
+++ b/setup.c
@@ -525,13 +525,17 @@ const char *setup_git_directory(void)
/* If the work tree is not the default one, recompute prefix */
if (inside_work_tree < 0) {
+ const char *work_tree = get_git_work_tree();
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");
+ if (retval) {
+ if (!is_absolute_path(retval))
+ retval = make_absolute_path(retval);
+ strncpy(buffer, retval, PATH_MAX);
+ buffer[PATH_MAX] = '\0';
+ rel = get_relative_path(buffer, work_tree);
+ } else
+ rel = get_relative_cwd(buffer, PATH_MAX, work_tree);
return rel && *rel ? strcat(rel, "/") : NULL;
}
--
1.7.0.5.3.ga76e
next reply other threads:[~2010-05-23 0:10 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-23 0:07 Clemens Buchacher [this message]
2010-05-23 1:35 ` [PATCH] setup: do not change to work tree prematurely Jonathan Nieder
2010-05-23 9:14 ` Clemens Buchacher
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=20100523000719.GA32380@localhost \
--to=drizzd@aon.at \
--cc=fbriere@fbriere.net \
--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).