From 7ad96e51ca81974c417914edbc81a63e390c4301 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Tue, 15 Mar 2011 05:38:50 +0200 Subject: [PATCH] Remove duplicate refs in `git_reference_listall` --- src/refs.c | 29 ++++++++++++++++++----------- tests/t10-refs.c | 6 +++++- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/refs.c b/src/refs.c index b9d25a769..cb11159fb 100644 --- a/src/refs.c +++ b/src/refs.c @@ -546,6 +546,7 @@ cleanup: struct dirent_list_data { git_vector ref_list; + git_repository *repo; size_t repo_path_len; unsigned int list_flags; }; @@ -553,16 +554,18 @@ struct dirent_list_data { static int _dirent_loose_listall(void *_data, char *full_path) { struct dirent_list_data *data = (struct dirent_list_data *)_data; - char *file_path; + char *file_path = full_path + data->repo_path_len; if (gitfo_isdir(full_path) == GIT_SUCCESS) return gitfo_dirent(full_path, GIT_PATH_MAX, _dirent_loose_listall, _data); + /* do not add twice a reference that exists already in the packfile */ + if (git_hashtable_lookup(data->repo->references.packfile, file_path) != NULL) + return GIT_SUCCESS; + if ((data->list_flags & loose_guess_rtype(full_path)) == 0) return GIT_SUCCESS; /* we are filtering out this reference */ - file_path = full_path + data->repo_path_len; - return git_vector_insert(&data->ref_list, git__strdup(file_path)); } @@ -1336,15 +1339,9 @@ int git_reference_listall(git_strarray *array, git_repository *repo, unsigned in git_vector_init(&data.ref_list, 8, NULL); data.repo_path_len = strlen(repo->path_repository); data.list_flags = list_flags; + data.repo = repo; - git__joinpath(refs_path, repo->path_repository, GIT_REFS_DIR); - error = gitfo_dirent(refs_path, GIT_PATH_MAX, _dirent_loose_listall, &data); - - if (error < GIT_SUCCESS) { - git_vector_free(&data.ref_list); - return error; - } - + /* list all the packed references first */ if (list_flags & GIT_REF_PACKED) { const char *ref_name; void *_unused; @@ -1359,6 +1356,16 @@ int git_reference_listall(git_strarray *array, git_repository *repo, unsigned in ); } + /* now list the loose references, trying not to + * duplicate the ref names already in the packed-refs file */ + git__joinpath(refs_path, repo->path_repository, GIT_REFS_DIR); + error = gitfo_dirent(refs_path, GIT_PATH_MAX, _dirent_loose_listall, &data); + + if (error < GIT_SUCCESS) { + git_vector_free(&data.ref_list); + return error; + } + array->strings = (char **)data.ref_list.contents; array->count = data.ref_list.length; return GIT_SUCCESS; diff --git a/tests/t10-refs.c b/tests/t10-refs.c index c70fb69ce..2c4c8a2dd 100644 --- a/tests/t10-refs.c +++ b/tests/t10-refs.c @@ -716,7 +716,11 @@ BEGIN_TEST(list0, "try to list all the references in our test repo") must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); must_pass(git_reference_listall(&ref_list, repo, GIT_REF_LISTALL)); - must_be_true(ref_list.count == 8); /* 8 refs in total if we include the packed ones */ + + /* We have exactly 7 refs in total if we include the packed ones: + * there is a reference that exists both in the packfile and as + * loose, but we only list it once */ + must_be_true(ref_list.count == 7); git_strarray_free(&ref_list); git_repository_free(repo);