Skip to content

Commit 45f24e7

Browse files
committed
git_repository_init: stop traversing at windows root
Stop traversing the filesystem at the Windows directory root. We were calculating the filesystem root for the given directory to create, and walking up the filesystem hierarchy. We intended to stop when the traversal path length is equal to the root path length (ie, stopping at the root, since no path may be shorter than the root path). However, on Windows, the root path may be specified in two different ways, as either `Z:` or `Z:\`, where `Z:` is the current drive letter. `git_path_dirname_r` returns the path _without_ a trailing slash, even for the Windows root. As a result, during traversal, we need to test that the traversal path is _less than or equal to_ the root path length to determine if we've hit the root to ensure that we stop when our traversal path is `Z:` and our calculated root path was `Z:\`.
1 parent d1cfd79 commit 45f24e7

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

src/fileops.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,13 @@ int git_futils_mkdir(
489489

490490
assert(len);
491491

492-
/* we've walked all the given path's parents and it's either relative
493-
* or rooted. either way, give up and make the entire path.
492+
/*
493+
* We've walked all the given path's parents and it's either relative
494+
* (the parent is simply '.') or rooted (the length is less than or
495+
* equal to length of the root path). The path may be less than the
496+
* root path length on Windows, where `C:` == `C:/`.
494497
*/
495-
if ((len == 1 && parent_path.ptr[0] == '.') || len == root_len+1) {
498+
if ((len == 1 && parent_path.ptr[0] == '.') || len <= root_len) {
496499
relative = make_path.ptr;
497500
break;
498501
}

tests/repo/init.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,3 +877,15 @@ void test_repo_init__at_filesystem_root(void)
877877
git_buf_dispose(&root);
878878
git_repository_free(repo);
879879
}
880+
881+
void test_repo_init__nonexistent_paths(void)
882+
{
883+
git_repository *repo;
884+
885+
#ifdef GIT_WIN32
886+
cl_git_fail(git_repository_init(&repo, "Q:/non/existent/path", 0));
887+
cl_git_fail(git_repository_init(&repo, "Q:\\non\\existent\\path", 0));
888+
#else
889+
cl_git_fail(git_repository_init(&repo, "/non/existent/path", 0));
890+
#endif
891+
}

0 commit comments

Comments
 (0)