From 33127043b3ef8dd8dd695ba3613eaa104a80a56b Mon Sep 17 00:00:00 2001 From: Brodie Rao Date: Fri, 14 Oct 2011 14:18:02 -0700 Subject: fileops/posix: replace usage of "int mode" with "mode_t mode" Note: Functions exported from fileops take const mode_t, while the underlying POSIX wrappers take mode_t. --- src/repository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/repository.c') diff --git a/src/repository.c b/src/repository.c index 328bc0d57..36642e5ae 100644 --- a/src/repository.c +++ b/src/repository.c @@ -609,7 +609,7 @@ static int repo_init_createhead(git_repository *repo) static int repo_init_structure(const char *git_dir, int is_bare) { - const int mode = 0755; /* or 0777 ? */ + const mode_t mode = 0755; /* or 0777 ? */ int error; char temp_path[GIT_PATH_MAX]; -- cgit v1.2.1 From ce8cd006ce3adcd012a38401b8a7555ba3307b3f Mon Sep 17 00:00:00 2001 From: Brodie Rao Date: Wed, 7 Sep 2011 15:32:44 -0700 Subject: fileops/repository: create (most) directories with 0777 permissions To further match how Git behaves, this change makes most of the directories libgit2 creates in a git repo have a file mode of 0777. Specifically: - Intermediate directories created with git_futils_mkpath2file() have 0777 permissions. This affects odb_loose, reflog, and refs. - The top level folder for bare repos is created with 0777 permissions. - The top level folder for non-bare repos is created with 0755 permissions. - /objects/info/, /objects/pack/, /refs/heads/, and /refs/tags/ are created with 0777 permissions. Additionally, the following changes have been made: - fileops functions that create intermediate directories have grown a new dirmode parameter. The only exception to this is filebuf's lock_file(), which unconditionally creates intermediate directories with 0777 permissions when GIT_FILEBUF_FORCE is set. - The test runner now sets the umask to 0 before running any tests. This ensurses all file mode checks are consistent across systems. - t09-tree.c now does a directory permissions check. I've avoided adding this check to other tests that might reuse existing directories from the prefabricated test repos. Because they're checked into the repo, they have 0755 permissions. - Other assorted directories created by tests have 0777 permissions. --- src/repository.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/repository.c') diff --git a/src/repository.c b/src/repository.c index 36642e5ae..d583cad6a 100644 --- a/src/repository.c +++ b/src/repository.c @@ -609,12 +609,11 @@ static int repo_init_createhead(git_repository *repo) static int repo_init_structure(const char *git_dir, int is_bare) { - const mode_t mode = 0755; /* or 0777 ? */ int error; char temp_path[GIT_PATH_MAX]; - if (git_futils_mkdir_r(git_dir, mode)) + if (git_futils_mkdir_r(git_dir, is_bare ? GIT_BARE_DIR_MODE : GIT_DIR_MODE)) return git__throw(GIT_ERROR, "Failed to initialize repository structure. Could not mkdir"); /* Hides the ".git" directory */ @@ -628,25 +627,25 @@ static int repo_init_structure(const char *git_dir, int is_bare) /* Creates the '/objects/info/' directory */ git_path_join(temp_path, git_dir, GIT_OBJECTS_INFO_DIR); - error = git_futils_mkdir_r(temp_path, mode); + error = git_futils_mkdir_r(temp_path, GIT_OBJECT_DIR_MODE); if (error < GIT_SUCCESS) return git__rethrow(error, "Failed to initialize repository structure"); /* Creates the '/objects/pack/' directory */ git_path_join(temp_path, git_dir, GIT_OBJECTS_PACK_DIR); - error = p_mkdir(temp_path, mode); + error = p_mkdir(temp_path, GIT_OBJECT_DIR_MODE); if (error < GIT_SUCCESS) return git__throw(error, "Unable to create `%s` folder", temp_path); /* Creates the '/refs/heads/' directory */ git_path_join(temp_path, git_dir, GIT_REFS_HEADS_DIR); - error = git_futils_mkdir_r(temp_path, mode); + error = git_futils_mkdir_r(temp_path, GIT_REFS_DIR_MODE); if (error < GIT_SUCCESS) return git__rethrow(error, "Failed to initialize repository structure"); /* Creates the '/refs/tags/' directory */ git_path_join(temp_path, git_dir, GIT_REFS_TAGS_DIR); - error = p_mkdir(temp_path, mode); + error = p_mkdir(temp_path, GIT_REFS_DIR_MODE); if (error < GIT_SUCCESS) return git__throw(error, "Unable to create `%s` folder", temp_path); -- cgit v1.2.1 From 3286c408eccb18c525ca123383f3ebf5097441bc Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Fri, 28 Oct 2011 14:51:13 -0700 Subject: global: Properly use `git__` memory wrappers Ensure that all memory related functions (malloc, calloc, strdup, free, etc) are using their respective `git__` wrappers. --- src/repository.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/repository.c') diff --git a/src/repository.c b/src/repository.c index 328bc0d57..33a3f270b 100644 --- a/src/repository.c +++ b/src/repository.c @@ -168,12 +168,12 @@ static git_repository *repository_alloc(void) error = git_cache_init(&repo->objects, GIT_DEFAULT_CACHE_SIZE, &git_object__free); if (error < GIT_SUCCESS) { - free(repo); + git__free(repo); return NULL; } if (git_repository__refcache_init(&repo->references) < GIT_SUCCESS) { - free(repo); + git__free(repo); return NULL; } @@ -467,13 +467,13 @@ static int read_gitfile(char *path_out, const char *file_path, const char *base_ static void git_repository__free_dirs(git_repository *repo) { - free(repo->path_workdir); + git__free(repo->path_workdir); repo->path_workdir = NULL; - free(repo->path_index); + git__free(repo->path_index); repo->path_index = NULL; - free(repo->path_repository); + git__free(repo->path_repository); repo->path_repository = NULL; - free(repo->path_odb); + git__free(repo->path_odb); repo->path_odb = NULL; } @@ -489,7 +489,7 @@ void git_repository_free(git_repository *repo) if (repo->db != NULL) git_odb_close(repo->db); - free(repo); + git__free(repo); } int git_repository_discover(char *repository_path, size_t size, const char *start_path, int across_fs, const char *ceiling_dirs) -- cgit v1.2.1 From 75abd2b92452782a9e6cee6ed5041339bd00c5bf Mon Sep 17 00:00:00 2001 From: schu Date: Thu, 11 Aug 2011 19:38:13 +0200 Subject: Free all used references in the source tree Since references are not owned by the repository anymore we have to free them manually now. Signed-off-by: schu --- src/repository.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'src/repository.c') diff --git a/src/repository.c b/src/repository.c index 849e1a9cf..6c75aa190 100644 --- a/src/repository.c +++ b/src/repository.c @@ -603,8 +603,14 @@ static int repo_init_reinit(const char *repository_path, int is_bare) static int repo_init_createhead(git_repository *repo) { + int error; git_reference *head_reference; - return git_reference_create_symbolic(&head_reference, repo, GIT_HEAD_FILE, GIT_REFS_HEADS_MASTER_FILE, 0); + + error = git_reference_create_symbolic(&head_reference, repo, GIT_HEAD_FILE, GIT_REFS_HEADS_MASTER_FILE, 0); + + git_reference_free(head_reference); + + return error; } static int repo_init_structure(const char *git_dir, int is_bare) @@ -715,10 +721,15 @@ int git_repository_head_detached(git_repository *repo) if (error < GIT_SUCCESS) return error; - if (git_reference_type(ref) == GIT_REF_SYMBOLIC) + if (git_reference_type(ref) == GIT_REF_SYMBOLIC) { + git_reference_free(ref); return 0; + } error = git_odb_read_header(&_size, &type, repo->db, git_reference_oid(ref)); + + git_reference_free(ref); + if (error < GIT_SUCCESS) return error; @@ -730,7 +741,7 @@ int git_repository_head_detached(git_repository *repo) int git_repository_head(git_reference **head_out, git_repository *repo) { - git_reference *ref; + git_reference *ref, *resolved_ref; int error; *head_out = NULL; @@ -739,11 +750,15 @@ int git_repository_head(git_reference **head_out, git_repository *repo) if (error < GIT_SUCCESS) return git__rethrow(GIT_ENOTAREPO, "Failed to locate the HEAD"); - error = git_reference_resolve(&ref, ref); - if (error < GIT_SUCCESS) + error = git_reference_resolve(&resolved_ref, ref); + if (error < GIT_SUCCESS) { + git_reference_free(ref); return git__rethrow(error, "Failed to resolve the HEAD"); + } - *head_out = ref; + git_reference_free(ref); + + *head_out = resolved_ref; return GIT_SUCCESS; } @@ -754,6 +769,9 @@ int git_repository_head_orphan(git_repository *repo) error = git_repository_head(&ref, repo); + if (error == GIT_SUCCESS) + git_reference_free(ref); + return error == GIT_ENOTFOUND ? 1 : error; } @@ -766,13 +784,21 @@ int git_repository_is_empty(git_repository *repo) if (error < GIT_SUCCESS) return git__throw(error, "Corrupted repository. HEAD does not exist"); - if (git_reference_type(head) != GIT_REF_SYMBOLIC) + if (git_reference_type(head) != GIT_REF_SYMBOLIC) { + git_reference_free(head); return 0; + } - if (strcmp(git_reference_target(head), "refs/heads/master") != 0) + if (strcmp(git_reference_target(head), "refs/heads/master") != 0) { + git_reference_free(head); return 0; + } error = git_reference_resolve(&branch, head); + + git_reference_free(head); + git_reference_free(branch); + return error == GIT_ENOTFOUND ? 1 : error; } -- cgit v1.2.1 From d4a0b124d00c70933d7c6ac9065c401cc2d70b2e Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Sun, 30 Oct 2011 21:58:33 -0700 Subject: refs: Partial rewrite for read-only refs This new version of the references code is significantly faster and hopefully easier to read. External API stays the same. A new method `git_reference_reload()` has been added to force updating a memory reference from disk. In-memory references are no longer updated automagically -- this was killing us. If a reference is deleted externally and the user doesn't reload the memory object, nothing critical happens: any functions using that reference should fail gracefully (e.g. deletion, renaming, and so on). All generated references from the API are read only and must be free'd by the user. There is no reference counting and no traces of generated references are kept in the library. There is no longer an internal representation for references. There is only one reference struct `git_reference`, and symbolic/oid targets are stored inside an union. Packfile references are stored using an optimized struct with flex array for reference names. This should significantly reduce the memory cost of loading the packfile from disk. --- src/repository.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/repository.c') diff --git a/src/repository.c b/src/repository.c index 6c75aa190..f8195e2d9 100644 --- a/src/repository.c +++ b/src/repository.c @@ -172,11 +172,6 @@ static git_repository *repository_alloc(void) return NULL; } - if (git_repository__refcache_init(&repo->references) < GIT_SUCCESS) { - git__free(repo); - return NULL; - } - return repo; } @@ -777,7 +772,7 @@ int git_repository_head_orphan(git_repository *repo) int git_repository_is_empty(git_repository *repo) { - git_reference *head, *branch; + git_reference *head = NULL, *branch = NULL; int error; error = git_reference_lookup(&head, repo, "HEAD"); -- cgit v1.2.1