From a41e9f131e0f62e2c45ed971a11ea557fe3a5ff8 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 13 Oct 2011 22:48:07 +0200 Subject: [PATCH 1/5] Fix compilation error on Windows --- src/transports/http.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/transports/http.c b/src/transports/http.c index 3426b34e1..680354bae 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -502,7 +502,6 @@ cleanup: static int http_negotiate_fetch(git_transport *transport, git_repository *repo, git_headarray *wants) { transport_http *t = (transport_http *) transport; - GIT_UNUSED_ARG(list); int error; unsigned int i; char buff[128]; From b3f993e28738b305c00315bd91a57f95a4bb552a Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sun, 9 Oct 2011 13:13:49 +0200 Subject: [PATCH 2/5] Add test commit containing subtrees and files --- .../1f/67fc4386b2d171e0d21be1c447e12660561f9b | Bin 0 -> 21 bytes .../27/0b8ea76056d5cad83af921837702d3e3c2924d | Bin 0 -> 21 bytes .../32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 | Bin 0 -> 50 bytes .../76/3d71aadf09a7951596c9746c024e7eece7c7af | Bin 0 -> 175 bytes .../9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 | Bin 0 -> 50 bytes .../ae/90f12eea699729ed24555e40b9fd669da12a12 | Bin 0 -> 148 bytes .../b6/361fc6a97178d8fc8639fdeed71c775ab52593 | Bin 0 -> 80 bytes .../d6/c93164c249c8000205dd4ec5cbca1b516d487f | Bin 0 -> 21 bytes .../e7/b4ad382349ff96dd8199000580b9b1e2042eb0 | Bin 0 -> 21 bytes .../f1/425cef211cc08caa31e7b545ffb232acb098c3 | Bin 0 -> 103 bytes tests/resources/testrepo.git/refs/heads/subtrees | Bin 0 -> 41 bytes tests/t10-refs.c | 4 ++-- 12 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 tests/resources/testrepo.git/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b create mode 100644 tests/resources/testrepo.git/objects/27/0b8ea76056d5cad83af921837702d3e3c2924d create mode 100644 tests/resources/testrepo.git/objects/32/59a6bd5b57fb9c1281bb7ed3167b50f224cb54 create mode 100644 tests/resources/testrepo.git/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af create mode 100644 tests/resources/testrepo.git/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 create mode 100644 tests/resources/testrepo.git/objects/ae/90f12eea699729ed24555e40b9fd669da12a12 create mode 100644 tests/resources/testrepo.git/objects/b6/361fc6a97178d8fc8639fdeed71c775ab52593 create mode 100644 tests/resources/testrepo.git/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f create mode 100644 tests/resources/testrepo.git/objects/e7/b4ad382349ff96dd8199000580b9b1e2042eb0 create mode 100644 tests/resources/testrepo.git/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 create mode 100644 tests/resources/testrepo.git/refs/heads/subtrees diff --git a/tests/resources/testrepo.git/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b b/tests/resources/testrepo.git/objects/1f/67fc4386b2d171e0d21be1c447e12660561f9b new file mode 100644 index 0000000000000000000000000000000000000000..225c45734e0bc525ec231bcba0d6ffd2e335a5d0 GIT binary patch literal 21 dcmby-a%8?0t#9e}{dDH^=1pybKbl G{96FXClfjV literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo.git/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af b/tests/resources/testrepo.git/objects/76/3d71aadf09a7951596c9746c024e7eece7c7af new file mode 100644 index 0000000000000000000000000000000000000000..716b0c64bf4bf8236f823c22c3cc059411bf968d GIT binary patch literal 175 zcmV;g08syU0iBLPY6Kw^1+(@Pe?Ks&qu&<7FgeO^eVs_!HmH67^ce>&+>vWv^KHD!2`b0%9>As;?8L#guWxuCZpJX0pF+T7T=%%gK>ay45#GASL d%9%#1psnl}RF2tboNF!}X|`T4)IU(XQY@}xR)YWl literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo.git/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 b/tests/resources/testrepo.git/objects/9a/03079b8a8ee85a0bee58bf9be3da8b62414ed4 new file mode 100644 index 0000000000000000000000000000000000000000..bf7b2bb686f9d563f6af7ded70cfee2a31432731 GIT binary patch literal 50 zcmV-20L}k+0V^p=O;s>9W-v4`Ff%bxFxD%nC}B|N?pvM^cJ7F=Q|_FfcPQQ3!H%bn$g%5N`dHvVMD1*wTH+ot*d0HmhE8 zio?VJ2ow^N7(P11yjPSt(6h?$`BvBen~c_Mm~j}YJ*g-$FF7MVEi)%oucV@c!F6Zz zKC|sM>>YRJ?Ae~PyWvmuhH$9Tywq~Al3$)1%BL$&TpPh$5b$Yve97Z6W-v4`Ff%bxFw!fjC}DWMWvzv>=l^MU8)q`GHtgK^h(&LM mi2)EOq@`yt7)37I8y)_8j!@(7y31nK0iRS(hX4SGX&b5U?IBwL literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo.git/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f b/tests/resources/testrepo.git/objects/d6/c93164c249c8000205dd4ec5cbca1b516d487f new file mode 100644 index 0000000000000000000000000000000000000000..a67d6e647ccc1f3faad53aa928441dcf66808c42 GIT binary patch literal 21 dcmb003G-2nPTF literal 0 HcmV?d00001 diff --git a/tests/resources/testrepo.git/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 b/tests/resources/testrepo.git/objects/f1/425cef211cc08caa31e7b545ffb232acb098c3 new file mode 100644 index 0000000000000000000000000000000000000000..82e2790e82869f7ebc516f291a2f2d0312f40660 GIT binary patch literal 103 zcmV-t0GR)H0V^p=O;xZoU@$Z=Ff%bxFwrZiC}FsE(lF(a=LrTT*1LX3PoI(w%=M@@ zF#rOEWQJMH?6bT2UPN)fi`YN=@vZJ8N53l&xs+6fZD#VvRu)#=_|s Date: Tue, 11 Oct 2011 14:42:48 +0200 Subject: [PATCH 3/5] Fix minor indentation issues --- tests/t09-tree.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/t09-tree.c b/tests/t09-tree.c index 543aea8d4..3af06ea67 100644 --- a/tests/t09-tree.c +++ b/tests/t09-tree.c @@ -187,22 +187,22 @@ BEGIN_TEST(write3, "write a hierarchical tree from a memory") must_pass(git_treebuilder_write(&subtree_id,repo,builder)); git_treebuilder_free(builder); - // create parent tree - must_pass(git_tree_lookup(&tree, repo, &id)); + // create parent tree + must_pass(git_tree_lookup(&tree, repo, &id)); must_pass(git_treebuilder_create(&builder, tree)); must_pass(git_treebuilder_insert(NULL,builder,"new",&subtree_id,040000)); must_pass(git_treebuilder_write(&id_hiearar,repo,builder)); git_treebuilder_free(builder); git_tree_close(tree); - must_be_true(git_oid_cmp(&id_hiearar, &id3) == 0); + must_be_true(git_oid_cmp(&id_hiearar, &id3) == 0); - // check data is correct - must_pass(git_tree_lookup(&tree, repo, &id_hiearar)); - must_be_true(2 == git_tree_entrycount(tree)); + // check data is correct + must_pass(git_tree_lookup(&tree, repo, &id_hiearar)); + must_be_true(2 == git_tree_entrycount(tree)); git_tree_close(tree); - close_temp_repo(repo); + close_temp_repo(repo); END_TEST @@ -215,4 +215,3 @@ BEGIN_SUITE(tree) ADD_TEST(write2); ADD_TEST(write3); END_SUITE - From 34aff0100248dbf349240fd8edff4cc440062b40 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Wed, 12 Oct 2011 14:06:23 +0200 Subject: [PATCH 4/5] oid: Add git_oid_streq() which checks if an oid and an hex formatted string are equal --- include/git2/oid.h | 10 ++++ src/oid.c | 11 ++++ tests-clay/clay.h | 24 ++++---- tests-clay/clay_main.c | 123 ++++++++++++++++++++++------------------- tests-clay/core/oid.c | 18 ++++++ 5 files changed, 117 insertions(+), 69 deletions(-) create mode 100644 tests-clay/core/oid.c diff --git a/include/git2/oid.h b/include/git2/oid.h index f9636d1fc..b9824b887 100644 --- a/include/git2/oid.h +++ b/include/git2/oid.h @@ -149,6 +149,16 @@ GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b); */ GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, unsigned int len); +/** + * Check if an oid equals an hex formatted object id. + * + * @param a oid structure. + * @param str input hex string of an object id. + * @return GIT_ENOTOID if str is not a valid hex string, + * GIT_SUCCESS in case of a match, GIT_ERROR otherwise. + */ +GIT_EXTERN(int) git_oid_streq(const git_oid *a, const char *str); + /** * OID Shortener object */ diff --git a/src/oid.c b/src/oid.c index b47fa2c77..bbf19ea20 100644 --- a/src/oid.c +++ b/src/oid.c @@ -197,6 +197,17 @@ int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, unsigned int len) return 0; } +int git_oid_streq(const git_oid *a, const char *str) +{ + git_oid id; + int error; + + if ((error = git_oid_fromstr(&id, str)) < GIT_SUCCESS) + return git__rethrow(error, "Failed to convert '%s' to oid.", str); + + return git_oid_cmp(a, &id) == 0 ? GIT_SUCCESS : GIT_ERROR; +} + typedef short node_index; typedef union { diff --git a/tests-clay/clay.h b/tests-clay/clay.h index 184635e14..7e653cfcc 100644 --- a/tests-clay/clay.h +++ b/tests-clay/clay.h @@ -57,17 +57,6 @@ void cl_fixture_cleanup(const char *fixture_name); /** * Test method declarations */ -extern void test_status_single__hash_single_file(void); -extern void test_status_worktree__initialize(void); -extern void test_status_worktree__cleanup(void); -extern void test_status_worktree__whole_repository(void); -extern void test_status_worktree__empty_repository(void); -extern void test_network_remotes__initialize(void); -extern void test_network_remotes__cleanup(void); -extern void test_network_remotes__parsing(void); -extern void test_network_remotes__refspec_parsing(void); -extern void test_network_remotes__fnmatch(void); -extern void test_network_remotes__transform(void); extern void test_core_dirent__dont_traverse_dot(void); extern void test_core_dirent__traverse_subfolder(void); extern void test_core_dirent__traverse_slash_terminated_folder(void); @@ -76,6 +65,8 @@ extern void test_core_dirent__traverse_weird_filenames(void); extern void test_core_filebuf__0(void); extern void test_core_filebuf__1(void); extern void test_core_filebuf__2(void); +extern void test_core_oid__initialize(void); +extern void test_core_oid__streq(void); extern void test_core_path__0(void); extern void test_core_path__1(void); extern void test_core_path__2(void); @@ -91,5 +82,16 @@ extern void test_core_strtol__int64(void); extern void test_core_vector__0(void); extern void test_core_vector__1(void); extern void test_core_vector__2(void); +extern void test_network_remotes__initialize(void); +extern void test_network_remotes__cleanup(void); +extern void test_network_remotes__parsing(void); +extern void test_network_remotes__refspec_parsing(void); +extern void test_network_remotes__fnmatch(void); +extern void test_network_remotes__transform(void); +extern void test_status_single__hash_single_file(void); +extern void test_status_worktree__initialize(void); +extern void test_status_worktree__cleanup(void); +extern void test_status_worktree__whole_repository(void); +extern void test_status_worktree__empty_repository(void); #endif diff --git a/tests-clay/clay_main.c b/tests-clay/clay_main.c index cca23f422..dcd9ae842 100644 --- a/tests-clay/clay_main.c +++ b/tests-clay/clay_main.c @@ -660,107 +660,114 @@ cl_fs_cleanup(void) static const struct clay_func _all_callbacks[] = { - {"hash_single_file", &test_status_single__hash_single_file, 0}, - {"whole_repository", &test_status_worktree__whole_repository, 1}, - {"empty_repository", &test_status_worktree__empty_repository, 1}, - {"parsing", &test_network_remotes__parsing, 2}, - {"refspec_parsing", &test_network_remotes__refspec_parsing, 2}, - {"fnmatch", &test_network_remotes__fnmatch, 2}, - {"transform", &test_network_remotes__transform, 2}, - {"dont_traverse_dot", &test_core_dirent__dont_traverse_dot, 3}, - {"traverse_subfolder", &test_core_dirent__traverse_subfolder, 3}, - {"traverse_slash_terminated_folder", &test_core_dirent__traverse_slash_terminated_folder, 3}, - {"dont_traverse_empty_folders", &test_core_dirent__dont_traverse_empty_folders, 3}, - {"traverse_weird_filenames", &test_core_dirent__traverse_weird_filenames, 3}, - {"0", &test_core_filebuf__0, 4}, - {"1", &test_core_filebuf__1, 4}, - {"2", &test_core_filebuf__2, 4}, - {"0", &test_core_path__0, 5}, - {"1", &test_core_path__1, 5}, - {"2", &test_core_path__2, 5}, - {"5", &test_core_path__5, 5}, - {"6", &test_core_path__6, 5}, - {"delete_recursive", &test_core_rmdir__delete_recursive, 6}, - {"fail_to_delete_non_empty_dir", &test_core_rmdir__fail_to_delete_non_empty_dir, 6}, - {"0", &test_core_string__0, 7}, - {"1", &test_core_string__1, 7}, - {"int32", &test_core_strtol__int32, 8}, - {"int64", &test_core_strtol__int64, 8}, - {"0", &test_core_vector__0, 9}, - {"1", &test_core_vector__1, 9}, - {"2", &test_core_vector__2, 9} + {"dont_traverse_dot", &test_core_dirent__dont_traverse_dot, 0}, + {"traverse_subfolder", &test_core_dirent__traverse_subfolder, 0}, + {"traverse_slash_terminated_folder", &test_core_dirent__traverse_slash_terminated_folder, 0}, + {"dont_traverse_empty_folders", &test_core_dirent__dont_traverse_empty_folders, 0}, + {"traverse_weird_filenames", &test_core_dirent__traverse_weird_filenames, 0}, + {"0", &test_core_filebuf__0, 1}, + {"1", &test_core_filebuf__1, 1}, + {"2", &test_core_filebuf__2, 1}, + {"streq", &test_core_oid__streq, 2}, + {"0", &test_core_path__0, 3}, + {"1", &test_core_path__1, 3}, + {"2", &test_core_path__2, 3}, + {"5", &test_core_path__5, 3}, + {"6", &test_core_path__6, 3}, + {"delete_recursive", &test_core_rmdir__delete_recursive, 4}, + {"fail_to_delete_non_empty_dir", &test_core_rmdir__fail_to_delete_non_empty_dir, 4}, + {"0", &test_core_string__0, 5}, + {"1", &test_core_string__1, 5}, + {"int32", &test_core_strtol__int32, 6}, + {"int64", &test_core_strtol__int64, 6}, + {"0", &test_core_vector__0, 7}, + {"1", &test_core_vector__1, 7}, + {"2", &test_core_vector__2, 7}, + {"parsing", &test_network_remotes__parsing, 8}, + {"refspec_parsing", &test_network_remotes__refspec_parsing, 8}, + {"fnmatch", &test_network_remotes__fnmatch, 8}, + {"transform", &test_network_remotes__transform, 8}, + {"hash_single_file", &test_status_single__hash_single_file, 9}, + {"whole_repository", &test_status_worktree__whole_repository, 10}, + {"empty_repository", &test_status_worktree__empty_repository, 10} }; static const struct clay_suite _all_suites[] = { { - "status::single", - {NULL, NULL, 0}, - {NULL, NULL, 0}, - &_all_callbacks[0], 1 - }, - { - "status::worktree", - {"initialize", &test_status_worktree__initialize, 1}, - {"cleanup", &test_status_worktree__cleanup, 1}, - &_all_callbacks[1], 2 - }, - { - "network::remotes", - {"initialize", &test_network_remotes__initialize, 2}, - {"cleanup", &test_network_remotes__cleanup, 2}, - &_all_callbacks[3], 4 - }, - { "core::dirent", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[7], 5 + &_all_callbacks[0], 5 }, { "core::filebuf", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[12], 3 + &_all_callbacks[5], 3 + }, + { + "core::oid", + {"initialize", &test_core_oid__initialize, 2}, + {NULL, NULL, 0}, + &_all_callbacks[8], 1 }, { "core::path", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[15], 5 + &_all_callbacks[9], 5 }, { "core::rmdir", - {"initialize", &test_core_rmdir__initialize, 6}, + {"initialize", &test_core_rmdir__initialize, 4}, {NULL, NULL, 0}, - &_all_callbacks[20], 2 + &_all_callbacks[14], 2 }, { "core::string", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[22], 2 + &_all_callbacks[16], 2 }, { "core::strtol", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[24], 2 + &_all_callbacks[18], 2 }, { "core::vector", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[26], 3 + &_all_callbacks[20], 3 + }, + { + "network::remotes", + {"initialize", &test_network_remotes__initialize, 8}, + {"cleanup", &test_network_remotes__cleanup, 8}, + &_all_callbacks[23], 4 + }, + { + "status::single", + {NULL, NULL, 0}, + {NULL, NULL, 0}, + &_all_callbacks[27], 1 + }, + { + "status::worktree", + {"initialize", &test_status_worktree__initialize, 10}, + {"cleanup", &test_status_worktree__cleanup, 10}, + &_all_callbacks[28], 2 } }; -static const char _suites_str[] = "status::single, status::worktree, network::remotes, core::dirent, core::filebuf, core::path, core::rmdir, core::string, core::strtol, core::vector"; +static const char _suites_str[] = "core::dirent, core::filebuf, core::oid, core::path, core::rmdir, core::string, core::strtol, core::vector, network::remotes, status::single, status::worktree"; int _MAIN_CC main(int argc, char *argv[]) { return clay_test( argc, argv, _suites_str, - _all_callbacks, 29, - _all_suites, 10 + _all_callbacks, 30, + _all_suites, 11 ); } diff --git a/tests-clay/core/oid.c b/tests-clay/core/oid.c new file mode 100644 index 000000000..44597c5ae --- /dev/null +++ b/tests-clay/core/oid.c @@ -0,0 +1,18 @@ +#include "clay_libgit2.h" + +static git_oid id; +const char *str_oid = "ae90f12eea699729ed24555e40b9fd669da12a12"; + +void test_core_oid__initialize(void) +{ + cl_git_pass(git_oid_fromstr(&id, str_oid)); +} + +void test_core_oid__streq(void) +{ + cl_assert(git_oid_streq(&id, str_oid) == GIT_SUCCESS); + cl_assert(git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == GIT_ERROR); + + cl_assert(git_oid_streq(&id, "deadbeef") == GIT_ENOTOID); + cl_assert(git_oid_streq(&id, "I'm not an oid.... :)") == GIT_ENOTOID); +} \ No newline at end of file From 3fa735ca3b8d8f855e43be44b5f96e59909d50e1 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Thu, 13 Oct 2011 23:17:19 +0200 Subject: [PATCH 5/5] tree: Add git_tree_frompath() which, given a relative path to a tree entry, retrieves the tree object containing this tree entry --- include/git2/tree.h | 14 ++++++ src/tree.c | 45 ++++++++++++++++++ tests-clay/clay.h | 5 ++ tests-clay/clay_main.c | 29 ++++++++---- tests-clay/object/tree/frompath.c | 76 +++++++++++++++++++++++++++++++ 5 files changed, 159 insertions(+), 10 deletions(-) create mode 100644 tests-clay/object/tree/frompath.c diff --git a/include/git2/tree.h b/include/git2/tree.h index d781ea136..8d638f723 100644 --- a/include/git2/tree.h +++ b/include/git2/tree.h @@ -268,6 +268,20 @@ GIT_EXTERN(void) git_treebuilder_filter(git_treebuilder *bld, int (*filter)(cons */ GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld); +/** + * Retrieve the tree object containing a tree entry, given + * a relative path to this tree entry + * + * The returned tree is owned by the repository and + * should be closed with the `git_object_close` method. + * + * @param parent_out Pointer where to store the parent tree + * @param root A previously loaded tree which will be the root of the relative path + * @param treeentry_path Path to the tree entry from which to extract the last tree object + * @return GIT_SUCCESS on success; GIT_ENOTFOUND if the path does not lead to an + * entry, GIT_EINVALIDPATH or an error code + */ +GIT_EXTERN(int) git_tree_frompath(git_tree **parent_out, git_tree *root, const char *treeentry_path); /** @} */ GIT_END_DECL #endif diff --git a/src/tree.c b/src/tree.c index 0acf74ede..3801df1dd 100644 --- a/src/tree.c +++ b/src/tree.c @@ -559,4 +559,49 @@ void git_treebuilder_free(git_treebuilder *bld) free(bld); } +static int tree_frompath(git_tree **parent_out, git_tree *root, const char *treeentry_path, int offset) +{ + char *slash_pos = NULL; + const git_tree_entry* entry; + int error = GIT_SUCCESS; + git_tree *subtree; + if (!*(treeentry_path + offset)) + return git__rethrow(GIT_EINVALIDPATH, "Invalid relative path to a tree entry '%s'.", treeentry_path); + + slash_pos = (char *)strchr(treeentry_path + offset, '/'); + + if (slash_pos == NULL) + return git_tree_lookup(parent_out, root->object.repo, git_object_id((const git_object *)root)); + + if (slash_pos == treeentry_path + offset) + return git__rethrow(GIT_EINVALIDPATH, "Invalid relative path to a tree entry '%s'.", treeentry_path); + + *slash_pos = '\0'; + + entry = git_tree_entry_byname(root, treeentry_path + offset); + + if (slash_pos != NULL) + *slash_pos = '/'; + + if (entry == NULL) + return git__rethrow(GIT_ENOTFOUND, "No tree entry can be found from the given tree and relative path '%s'.", treeentry_path); + + if ((error = git_tree_lookup(&subtree, root->object.repo, &entry->oid)) < GIT_SUCCESS) + return error; + + error = tree_frompath(parent_out, subtree, treeentry_path, slash_pos - treeentry_path + 1); + + git_tree_close(subtree); + return error; +} + +int git_tree_frompath(git_tree **parent_out, git_tree *root, const char *treeentry_path) +{ + char buffer[GIT_PATH_MAX]; + + assert(root && treeentry_path); + + strcpy(buffer, treeentry_path); + return tree_frompath(parent_out, root, buffer, 0); +} diff --git a/tests-clay/clay.h b/tests-clay/clay.h index 7e653cfcc..bc4267b66 100644 --- a/tests-clay/clay.h +++ b/tests-clay/clay.h @@ -88,6 +88,11 @@ extern void test_network_remotes__parsing(void); extern void test_network_remotes__refspec_parsing(void); extern void test_network_remotes__fnmatch(void); extern void test_network_remotes__transform(void); +extern void test_object_tree_frompath__initialize(void); +extern void test_object_tree_frompath__cleanup(void); +extern void test_object_tree_frompath__retrieve_tree_from_path_to_treeentry(void); +extern void test_object_tree_frompath__fail_when_processing_an_unknown_tree_segment(void); +extern void test_object_tree_frompath__fail_when_processing_an_invalid_path(void); extern void test_status_single__hash_single_file(void); extern void test_status_worktree__initialize(void); extern void test_status_worktree__cleanup(void); diff --git a/tests-clay/clay_main.c b/tests-clay/clay_main.c index dcd9ae842..da90872ce 100644 --- a/tests-clay/clay_main.c +++ b/tests-clay/clay_main.c @@ -687,9 +687,12 @@ static const struct clay_func _all_callbacks[] = { {"refspec_parsing", &test_network_remotes__refspec_parsing, 8}, {"fnmatch", &test_network_remotes__fnmatch, 8}, {"transform", &test_network_remotes__transform, 8}, - {"hash_single_file", &test_status_single__hash_single_file, 9}, - {"whole_repository", &test_status_worktree__whole_repository, 10}, - {"empty_repository", &test_status_worktree__empty_repository, 10} + {"retrieve_tree_from_path_to_treeentry", &test_object_tree_frompath__retrieve_tree_from_path_to_treeentry, 9}, + {"fail_when_processing_an_unknown_tree_segment", &test_object_tree_frompath__fail_when_processing_an_unknown_tree_segment, 9}, + {"fail_when_processing_an_invalid_path", &test_object_tree_frompath__fail_when_processing_an_invalid_path, 9}, + {"hash_single_file", &test_status_single__hash_single_file, 10}, + {"whole_repository", &test_status_worktree__whole_repository, 11}, + {"empty_repository", &test_status_worktree__empty_repository, 11} }; static const struct clay_suite _all_suites[] = { @@ -746,28 +749,34 @@ static const struct clay_suite _all_suites[] = { {"initialize", &test_network_remotes__initialize, 8}, {"cleanup", &test_network_remotes__cleanup, 8}, &_all_callbacks[23], 4 + }, + { + "object::tree::frompath", + {"initialize", &test_object_tree_frompath__initialize, 9}, + {"cleanup", &test_object_tree_frompath__cleanup, 9}, + &_all_callbacks[27], 3 }, { "status::single", {NULL, NULL, 0}, {NULL, NULL, 0}, - &_all_callbacks[27], 1 + &_all_callbacks[30], 1 }, { "status::worktree", - {"initialize", &test_status_worktree__initialize, 10}, - {"cleanup", &test_status_worktree__cleanup, 10}, - &_all_callbacks[28], 2 + {"initialize", &test_status_worktree__initialize, 11}, + {"cleanup", &test_status_worktree__cleanup, 11}, + &_all_callbacks[31], 2 } }; -static const char _suites_str[] = "core::dirent, core::filebuf, core::oid, core::path, core::rmdir, core::string, core::strtol, core::vector, network::remotes, status::single, status::worktree"; +static const char _suites_str[] = "core::dirent, core::filebuf, core::oid, core::path, core::rmdir, core::string, core::strtol, core::vector, network::remotes, object::tree::frompath, status::single, status::worktree"; int _MAIN_CC main(int argc, char *argv[]) { return clay_test( argc, argv, _suites_str, - _all_callbacks, 30, - _all_suites, 11 + _all_callbacks, 33, + _all_suites, 12 ); } diff --git a/tests-clay/object/tree/frompath.c b/tests-clay/object/tree/frompath.c new file mode 100644 index 000000000..33a76e8aa --- /dev/null +++ b/tests-clay/object/tree/frompath.c @@ -0,0 +1,76 @@ +#include "clay_libgit2.h" + +#define REPOSITORY_FOLDER "testrepo.git" + +static git_repository *repo; +const char *tree_with_subtrees_oid = "ae90f12eea699729ed24555e40b9fd669da12a12"; +static git_tree *tree; + +void test_object_tree_frompath__initialize(void) +{ + git_oid id; + + cl_fixture_sandbox(REPOSITORY_FOLDER); + cl_git_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + cl_assert(repo != NULL); + + cl_git_pass(git_oid_fromstr(&id, tree_with_subtrees_oid)); + cl_git_pass(git_tree_lookup(&tree, repo, &id)); + cl_assert(tree != NULL); +} + +void test_object_tree_frompath__cleanup(void) +{ + git_tree_close(tree); + git_repository_free(repo); +} + +static void assert_tree_from_path(git_tree *root, const char *path, git_error expected_result, const char *expected_raw_oid) +{ + git_tree *containing_tree = NULL; + + cl_assert(git_tree_frompath(&containing_tree, root, path) == expected_result); + + if (containing_tree == NULL && expected_result != GIT_SUCCESS) + return; + + cl_assert(containing_tree != NULL && expected_result == GIT_SUCCESS); + + cl_assert(git_oid_streq(git_object_id((const git_object *)containing_tree), expected_raw_oid) == GIT_SUCCESS); + + git_tree_close(containing_tree); +} + +void test_object_tree_frompath__retrieve_tree_from_path_to_treeentry(void) +{ + /* Will return self if given a one path segment... */ + assert_tree_from_path(tree, "README", GIT_SUCCESS, tree_with_subtrees_oid); + + /* ...even one that lead to a non existent tree entry. */ + assert_tree_from_path(tree, "i-do-not-exist.txt", GIT_SUCCESS, tree_with_subtrees_oid); + + /* Will return fgh tree oid given this following path... */ + assert_tree_from_path(tree, "ab/de/fgh/1.txt", GIT_SUCCESS, "3259a6bd5b57fb9c1281bb7ed3167b50f224cb54"); + + /* ... and ab tree oid given this one. */ + assert_tree_from_path(tree, "ab/de", GIT_SUCCESS, "f1425cef211cc08caa31e7b545ffb232acb098c3"); + + /* Will succeed if given a valid path which leads to a tree entry which doesn't exist */ + assert_tree_from_path(tree, "ab/de/fgh/i-do-not-exist.txt", GIT_SUCCESS, "3259a6bd5b57fb9c1281bb7ed3167b50f224cb54"); +} + +void test_object_tree_frompath__fail_when_processing_an_unknown_tree_segment(void) +{ + assert_tree_from_path(tree, "nope/de/fgh/1.txt", GIT_ENOTFOUND, NULL); + assert_tree_from_path(tree, "ab/me-neither/fgh/2.txt", GIT_ENOTFOUND, NULL); +} + +void test_object_tree_frompath__fail_when_processing_an_invalid_path(void) +{ + assert_tree_from_path(tree, "/", GIT_EINVALIDPATH, NULL); + assert_tree_from_path(tree, "/ab", GIT_EINVALIDPATH, NULL); + assert_tree_from_path(tree, "/ab/de", GIT_EINVALIDPATH, NULL); + assert_tree_from_path(tree, "ab/", GIT_EINVALIDPATH, NULL); + assert_tree_from_path(tree, "ab//de", GIT_EINVALIDPATH, NULL); + assert_tree_from_path(tree, "ab/de/", GIT_EINVALIDPATH, NULL); +}