Commit d5f2520413939b114bdb4da95e6b10ee60e67f4c

Vicent Marti 2011-01-03T21:37:14

Merge branch 'repo-init' of https://github.com/nulltoken/libgit2 into nulltoken-repo-init

diff --git a/src/fileops.c b/src/fileops.c
index 5d7e929..68f45c2 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -1,5 +1,6 @@
 #include "common.h"
 #include "fileops.h"
+#include <ctype.h>
 
 int gitfo_open(const char *path, int flags)
 {
@@ -311,6 +312,19 @@ int gitfo_dirent(
 	return GIT_SUCCESS;
 }
 
+#ifdef GIT_WIN32
+
+static int is_windows_rooted_path(const char *path)
+{
+	/* Does the root of the path look like a windows drive ? */
+	if (isalpha(path[0]) && (path[1] == ':'))
+		return GIT_SUCCESS;
+
+	return GIT_ERROR;
+}
+
+#endif
+
 int gitfo_mkdir_recurs(const char *path, int mode)
 {
 	int error;
@@ -320,23 +334,35 @@ int gitfo_mkdir_recurs(const char *path, int mode)
 	if (path_copy == NULL)
 		return GIT_ENOMEM;
 
-    error = GIT_SUCCESS;
-    pp = path_copy;
+	error = GIT_SUCCESS;
+	pp = path_copy;
 
-    while (error == 0 && (sp = strchr(pp, '/')) != 0) {
-        if (sp != pp && gitfo_isdir(path_copy) < GIT_SUCCESS) {
-            *sp = 0;
-            error = gitfo_mkdir(path_copy, mode);
-            *sp = '/';
-        }
+#ifdef GIT_WIN32
 
-        pp = sp + 1;
-    }
+	if (!is_windows_rooted_path(pp))
+		pp += 2; /* Skip the drive name (eg. C: or D:) */
+
+#endif
+
+    while (error == GIT_SUCCESS && (sp = strchr(pp, '/')) != 0) {
+		if (sp != pp && gitfo_isdir(path_copy) < GIT_SUCCESS) {
+			*sp = 0;
+			error = gitfo_mkdir(path_copy, mode);
+
+			/* Do not choke while trying to recreate an existing directory */
+			if (errno == EEXIST)
+				error = GIT_SUCCESS;
+
+			*sp = '/';
+		}
+
+		pp = sp + 1;
+	}
 
-    if (*(pp - 1) != '/' && error == GIT_SUCCESS)
-        error = gitfo_mkdir(path, mode);
+	if (*(pp - 1) != '/' && error == GIT_SUCCESS)
+		error = gitfo_mkdir(path, mode);
 
-    free(path_copy);
-    return error;
+	free(path_copy);
+	return error;
 
 }
diff --git a/src/repository.c b/src/repository.c
index 3551b87..6af75f7 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -35,9 +35,11 @@
 
 #define GIT_DIR "/.git/"
 #define GIT_OBJECTS_DIR "objects/"
+#define GIT_OBJECTS_INFO_DIR GIT_OBJECTS_DIR "info/"
+#define GIT_OBJECTS_PACK_DIR GIT_OBJECTS_DIR "pack/"
 #define GIT_REFS_DIR "refs/"
-#define GIT_REFS_HEADS_DIR "refs/heads/"
-#define GIT_REFS_TAGS_DIR "refs/tags/"
+#define GIT_REFS_HEADS_DIR GIT_REFS_DIR "heads/"
+#define GIT_REFS_TAGS_DIR GIT_REFS_DIR "tags/"
 
 #define GIT_INDEX_FILE "index"
 #define GIT_HEAD_FILE "HEAD"
@@ -786,19 +788,19 @@ int repo_init_structure(repo_init *results)
 	if (repo_init_createhead(temp_path) < GIT_SUCCESS)
 		return GIT_ERROR;
 
-	/* Creates the '/objects/' directory */
-	strcpy(temp_path + path_len, GIT_OBJECTS_DIR);
-	if (gitfo_mkdir(temp_path, mode))
+	/* Creates the '/objects/info/' directory */
+	strcpy(temp_path + path_len, GIT_OBJECTS_INFO_DIR);
+	if (gitfo_mkdir_recurs(temp_path, mode))
 		return GIT_ERROR;
 
-	/* Creates the '/refs/' directory */
-	strcpy(temp_path + path_len, GIT_REFS_DIR);
+	/* Creates the '/objects/pack/' directory */
+	strcpy(temp_path + path_len, GIT_OBJECTS_PACK_DIR);
 	if (gitfo_mkdir(temp_path, mode))
 		return GIT_ERROR;
 
 	/* Creates the '/refs/heads/' directory */
 	strcpy(temp_path + path_len, GIT_REFS_HEADS_DIR);
-	if (gitfo_mkdir(temp_path, mode))
+	if (gitfo_mkdir_recurs(temp_path, mode))
 		return GIT_ERROR;
 
 	/* Creates the '/refs/tags/' directory */