Merge branch 'repo-init' of https://github.com/nulltoken/libgit2 into nulltoken-repo-init
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
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 */