diff --git a/src/git2/repository.h b/src/git2/repository.h index 8a171cf3a..195a8aa29 100644 --- a/src/git2/repository.h +++ b/src/git2/repository.h @@ -59,7 +59,7 @@ GIT_BEGIN_DECL * * @param repository pointer to the repo which will be opened * @param path the path to the repository - * @return 0 on sucess; error code otherwise + * @return 0 on success; error code otherwise */ GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *path); @@ -88,7 +88,7 @@ GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *pat * Equivalent to $GIT_WORK_TREE. * If NULL, the repository is assumed to be bare. * - * @return 0 on sucess; error code otherwise + * @return 0 on success; error code otherwise */ GIT_EXTERN(int) git_repository_open2(git_repository **repository, const char *git_dir, @@ -162,7 +162,20 @@ GIT_EXTERN(int) git_repository_newobject(git_object **object, git_repository *re */ GIT_EXTERN(void) git_repository_free(git_repository *repo); -//TODO: Add comments. +/** + * Creates a new Git repository. + * + * Limits: + * - Reinit of an existing directory is not implemented yet. Will blindly return GIT_SUCCESS. + * - The parent directory structure of the repository has to already exist. Recursive building of the parent tree structure is not implmented yet. + * - Config file creation handling is not implemented yet. + * + * @param repo_out pointer to the repo which will be created or reinitialized + * @param path the path to the repository + * @param is_bare if true, a Git repository without a working directory is created at the pointed path. + * If false, provided path will be considered as the working directory into which the .git directory will be created. + * @return 0 on success; error code otherwise + */ GIT_EXTERN(int) git_repository_init(git_repository** repo_out, const char* path, unsigned is_bare); /** @} */ diff --git a/src/repository.c b/src/repository.c index 4e5e7e699..df154828f 100644 --- a/src/repository.c +++ b/src/repository.c @@ -739,7 +739,24 @@ int git_repository_init__reinit(git_repository_init_results* results) return GIT_SUCCESS; } -int git_repository_init__create_structure(git_repository_init_results* results) +int git_repository_init__create_head(const char* head_path) +{ + git_file fd; + int error = GIT_SUCCESS; + const char* head_content = "ref: refs/heads/master\n"; + if ((fd = gitfo_creat(head_path, S_IREAD | S_IWRITE)) < 0) + return GIT_ERROR; + + error = gitfo_write(fd, (void*)head_content, strlen(head_content)); + if (error < GIT_SUCCESS) + goto cleanup; + +cleanup: + gitfo_close(fd); + return error; +} + +int git_repository_init__create_structure_or_reinit(git_repository_init_results* results) { char temp_path[GIT_PATH_MAX]; int path_len; @@ -756,15 +773,27 @@ int git_repository_init__create_structure(git_repository_init_results* results) /* Does HEAD file already exist ? */ strcpy(temp_path + path_len, GIT_HEAD_FILE); + + if (!gitfo_exists(temp_path) && gitfo_isdir(temp_path) < GIT_SUCCESS) + { + /* Something very wrong has happened to this repository :-) */ + return GIT_ERROR; + } + if (!gitfo_exists(temp_path)) { return git_repository_init__reinit(results); } + if (git_repository_init__create_head(temp_path) < GIT_SUCCESS) + return GIT_ERROR; + + /* Creates the '/objects/' directory */ strcpy(temp_path + path_len, GIT_OBJECTS_FOLDER); if (gitfo_mkdir(temp_path, mode)) return GIT_ERROR; + /* Creates the '/refs/' directory */ strcpy(temp_path + path_len, GIT_REFS_FOLDER); if (gitfo_mkdir(temp_path, mode)) return GIT_ERROR; @@ -818,14 +847,13 @@ int git_repository_init(git_repository** repo_out, const char* path, unsigned is if (error < GIT_SUCCESS) goto cleanup; - error = git_repository_init__create_structure(&results); + error = git_repository_init__create_structure_or_reinit(&results); if (error < GIT_SUCCESS) goto cleanup; - //TODO: Uncomment when the structure has been properly created - //error = git_repository_open(repo_out, results->path_repository); - //if (error < GIT_SUCCESS) - // goto cleanup; + error = git_repository_open(repo_out, results.path_repository); + if (error < GIT_SUCCESS) + goto cleanup; cleanup: free(results.path_repository);