@matheusbsbs / matheus-bagliano / commits / 72ec8ba6dd
Fork 0

Support working directory located at root

Git should work regardless where the working directory is located, even at root. This patch fixes two places where it assumes working directory always have parent directory. In setup_git_directory_gently(), when Git goes up to root and finds .git there, it happily sets worktree to "" instead of "/". In prefix_path(), loosen the outside repo check a little bit. Usually when a path XXX is inside worktree /foo, it must be either "/foo", or "/foo/...". When worktree is simply "/", we can safely ignore the check: we have a slash at the beginning already. Not related to worktree, but also set gitdir correctly if a bare repo is placed (insanely?) at root. Thanks João Carlos Mendes Luís for pointing out this problem. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Feb 14, 2010 at 22:44 UTC 72ec8ba6dddbe2c53500d35d7ed343c153874fc6
1 file changed +10 -7
setup.c
+10 -7
@@ -18,14 +18,15 @@ const char *prefix_path(const char *prefix, int len, const char *path)
18 if (normalize_path_copy(sanitized, sanitized))
19 goto error_out;
20 if (is_absolute_path(orig)) {
21 - size_t len, total;
21 + size_t root_len, len, total;
22 const char *work_tree = get_git_work_tree();
23 if (!work_tree)
24 goto error_out;
25 len = strlen(work_tree);
26 + root_len = offset_1st_component(work_tree);
27 total = strlen(sanitized) + 1;
28 if (strncmp(sanitized, work_tree, len) ||
28 - (sanitized[len] != '\0' && sanitized[len] != '/')) {
29 + (len > root_len && sanitized[len] != '\0' && sanitized[len] != '/')) {
30 error_out:
31 die("'%s' is outside repository", orig);
32 }
@@ -294,7 +295,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
295 static char cwd[PATH_MAX+1];
296 const char *gitdirenv;
297 const char *gitfile_dir;
297 - int len, offset, ceil_offset;
298 + int len, offset, ceil_offset, root_len;
299
300 /*
301 * Let's assume that we are in a git repository.
@@ -376,10 +377,11 @@ const char *setup_git_directory_gently(int *nongit_ok)
377 if (!work_tree_env)
378 inside_work_tree = 0;
379 if (offset != len) {
379 - cwd[offset] = '\0';
380 - setenv(GIT_DIR_ENVIRONMENT, cwd, 1);
380 + root_len = offset_1st_component(cwd);
381 + cwd[offset > root_len ? offset : root_len] = '\0';
382 + set_git_dir(cwd);
383 } else
382 - setenv(GIT_DIR_ENVIRONMENT, ".", 1);
384 + set_git_dir(".");
385 check_repository_format_gently(nongit_ok);
386 return NULL;
387 }
@@ -400,7 +402,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
402 inside_git_dir = 0;
403 if (!work_tree_env)
404 inside_work_tree = 1;
403 - git_work_tree_cfg = xstrndup(cwd, offset);
405 + root_len = offset_1st_component(cwd);
406 + git_work_tree_cfg = xstrndup(cwd, offset > root_len ? offset : root_len);
407 if (check_repository_format_gently(nongit_ok))
408 return NULL;
409 if (offset == len)