diff --git a/include/git2/sys/repository.h b/include/git2/sys/repository.h index 34bc17516..ba3d65ae5 100644 --- a/include/git2/sys/repository.h +++ b/include/git2/sys/repository.h @@ -27,6 +27,20 @@ GIT_BEGIN_DECL */ GIT_EXTERN(int) git_repository_new(git_repository **out); + +/** + * Reset all the internal state in a repository. + * + * This will free all the mapped memory and internal objects + * of the repository and leave it in a "blank" state. + * + * There's no need to call this function directly unless you're + * trying to aggressively cleanup the repo before its + * deallocation. `git_repository_free` already performs this operation + * before deallocation the repo. + */ +GIT_EXTERN(void) git_repository__cleanup(git_repository *repo); + /** * Set the configuration file for this repository * diff --git a/src/cache.c b/src/cache.c index 88f643b35..be4b037a3 100644 --- a/src/cache.c +++ b/src/cache.c @@ -77,6 +77,9 @@ static void clear_cache(git_cache *cache) { git_cached_obj *evict = NULL; + if (kh_size(cache->map) == 0) + return; + kh_foreach_value(cache->map, evict, { git_cached_obj_decref(evict); }); diff --git a/src/cache.h b/src/cache.h index 1fb87dcea..16470e9c8 100644 --- a/src/cache.h +++ b/src/cache.h @@ -42,6 +42,7 @@ int git_cache_set_max_object_size(git_otype type, size_t size); int git_cache_init(git_cache *cache); void git_cache_free(git_cache *cache); +void git_cache_clear(git_cache *cache); void *git_cache_store_raw(git_cache *cache, git_odb_object *entry); void *git_cache_store_parsed(git_cache *cache, git_object *entry); diff --git a/src/repository.c b/src/repository.c index 59479dc92..2161aa697 100644 --- a/src/repository.c +++ b/src/repository.c @@ -86,19 +86,28 @@ static void set_index(git_repository *repo, git_index *index) } } -void git_repository_free(git_repository *repo) +void git_repository__cleanup(git_repository *repo) { - if (repo == NULL) - return; + assert(repo); - git_cache_free(&repo->objects); + git_cache_clear(&repo->objects); git_attr_cache_flush(repo); - git_submodule_config_free(repo); set_config(repo, NULL); set_index(repo, NULL); set_odb(repo, NULL); set_refdb(repo, NULL); +} + +void git_repository_free(git_repository *repo) +{ + if (repo == NULL) + return; + + git_repository__cleanup(repo); + + git_cache_free(&repo->objects); + git_submodule_config_free(repo); git__free(repo->path_repository); git__free(repo->workdir);