Skip to content

Commit

Permalink
setup: return correct prefix if worktree is '/'
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
pclouds authored and gitster committed Mar 29, 2011
1 parent 78bc466 commit 9b125da
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
31 changes: 31 additions & 0 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,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];
Expand Down
1 change: 1 addition & 0 deletions dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,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)
{
Expand Down
7 changes: 4 additions & 3 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,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);
Expand Down Expand Up @@ -387,15 +388,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(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;
return cwd + offset;
}

/* cwd outside worktree */
Expand Down

0 comments on commit 9b125da

Please sign in to comment.