Commit b3923cf7199a93dadcb31e727eeca5b3c6e16361

Edward Thomson 2019-04-17T13:43:52

Merge pull request #5050 from libgit2/ethomson/windows_init_traversal git_repository_init: stop traversing at windows root

diff --git a/src/fileops.c b/src/fileops.c
index 61906ed..a4d5cc6 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -489,10 +489,13 @@ int git_futils_mkdir(
 
 		assert(len);
 
-		/* we've walked all the given path's parents and it's either relative
-		 * or rooted.  either way, give up and make the entire path.
+		/*
+		 * We've walked all the given path's parents and it's either relative
+		 * (the parent is simply '.') or rooted (the length is less than or
+		 * equal to length of the root path).  The path may be less than the
+		 * root path length on Windows, where `C:` == `C:/`.
 		 */
-		if ((len == 1 && parent_path.ptr[0] == '.') || len == root_len+1) {
+		if ((len == 1 && parent_path.ptr[0] == '.') || len <= root_len) {
 			relative = make_path.ptr;
 			break;
 		}
diff --git a/tests/repo/init.c b/tests/repo/init.c
index 91b25a5..6e6e652 100644
--- a/tests/repo/init.c
+++ b/tests/repo/init.c
@@ -877,3 +877,15 @@ void test_repo_init__at_filesystem_root(void)
 	git_buf_dispose(&root);
 	git_repository_free(repo);
 }
+
+void test_repo_init__nonexistent_paths(void)
+{
+	git_repository *repo;
+
+#ifdef GIT_WIN32
+	cl_git_fail(git_repository_init(&repo, "Q:/non/existent/path", 0));
+	cl_git_fail(git_repository_init(&repo, "Q:\\non\\existent\\path", 0));
+#else
+	cl_git_fail(git_repository_init(&repo, "/non/existent/path", 0));
+#endif
+}