All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Michael J Gruber <git@drmicha.warpmail.net>,
	Matthijs Kooijman <matthijs@stdin.nl>,
	Junio C Hamano <gitster@pobox.com>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 1/2 v2] setup: return correct prefix if worktree is '/'
Date: Sat, 26 Mar 2011 16:04:24 +0700	[thread overview]
Message-ID: <1301130265-27287-1-git-send-email-pclouds@gmail.com> (raw)

The same old problem reappears after setup code is reworked.  We tend
to assume there is at least one path component in a path and forget
that path can be simply '/'.

Reported-by: Matthijs Kooijman <matthijs@stdin.nl>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 It just looks better than previous version.

 dir.c   |   31 +++++++++++++++++++++++++++++++
 dir.h   |    1 +
 setup.c |    7 ++++---
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/dir.c b/dir.c
index 325fb56..6c49a73 100644
--- a/dir.c
+++ b/dir.c
@@ -1152,6 +1152,37 @@ char *get_relative_cwd(char *buffer, int size, const char *dir)
 	}
 }
 
+ * Given two normalized paths (a trailing slash is ok), if subdir is
+ * outside dir, return -1.  Otherwise return the offset in subdir that
+ * can be used as relative path to dir.
+ */
+int dir_inside_of(const char *subdir, const char *dir)
+{
+	int offset = 0;
+
+	assert(dir && subdir && *dir && *subdir);
+
+	while (*dir && *subdir && *dir == *subdir) {
+		dir++;
+		subdir++;
+		offset++;
+	}
+
+	/* hel[p]/me vs hel[l]/yeah */
+	if (*dir && *subdir)
+		return -1;
+
+	if (!*subdir)
+		return !*dir ? offset : -1; /* same dir */
+
+	/* foo/[b]ar vs foo/[] */
+	if (is_dir_sep(dir[-1]))
+		return is_dir_sep(subdir[-1]) ? offset : -1;
+
+	/* foo[/]bar vs foo[] */
+	return is_dir_sep(*subdir) ? offset + 1 : -1;
+}
+
 int is_inside_dir(const char *dir)
 {
 	char buffer[PATH_MAX];
diff --git a/dir.h b/dir.h
index aa511da..83e2992 100644
--- a/dir.h
+++ b/dir.h
@@ -87,6 +87,7 @@ extern int file_exists(const char *);
 
 extern char *get_relative_cwd(char *buffer, int size, const char *dir);
 extern int is_inside_dir(const char *dir);
+extern int dir_inside_of(const char *subdir, const char *dir);
 
 static inline int is_dot_or_dotdot(const char *name)
 {
diff --git a/setup.c b/setup.c
index 03cd84f..b6e6b5a 100644
--- a/setup.c
+++ b/setup.c
@@ -325,6 +325,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
 	const char *worktree;
 	char *gitfile;
+	int offset;
 
 	if (PATH_MAX - 40 < strlen(gitdirenv))
 		die("'$%s' too big", GIT_DIR_ENVIRONMENT);
@@ -390,15 +391,15 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 		return NULL;
 	}
 
-	if (!prefixcmp(cwd, worktree) &&
-	    cwd[strlen(worktree)] == '/') { /* cwd inside worktree */
+	offset = dir_inside_of(cwd, worktree);
+	if (offset >= 0) {	/* cwd inside worktree? */
 		set_git_dir(real_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;
+		return cwd + offset;
 	}
 
 	/* cwd outside worktree */
-- 
1.7.4.74.g639db

             reply	other threads:[~2011-03-26  9:04 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-26  9:04 Nguyễn Thái Ngọc Duy [this message]
2011-03-26  9:04 ` [PATCH 2/2] Kill off get_relative_cwd() Nguyễn Thái Ngọc Duy

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=1301130265-27287-1-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@drmicha.warpmail.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=matthijs@stdin.nl \
    /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.