From 892aa808e2e879562c45f3d0886668f86265f1cf Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Mon, 10 Mar 2014 12:00:33 -0700 Subject: [PATCH 1/7] Callback to hide commits in revision walker. --- include/git2/revwalk.h | 24 ++++++++++++++++++++++++ src/revwalk.c | 28 ++++++++++++++++++++++++++++ src/revwalk.h | 4 ++++ 3 files changed, 56 insertions(+) diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h index aef0b5fa6..7ab082752 100644 --- a/include/git2/revwalk.h +++ b/include/git2/revwalk.h @@ -261,6 +261,30 @@ GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk); */ GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk); +/** +* This is a callback function that user can provide to hide a +* commit and its parents. If the callback function returns true, +* then this commit and its parents will be hidden. +* +* @param commit_id oid of Commit +* @param payload User-specified pointer to data to be passed as data payload +*/ +typedef int(*git_revwalk_hide_cb)( + const git_oid *commit_id, + void *payload); + +/** +* Adds a callback function to hide a commit +* +* @param walk the revision walker +* @param hide_cb callback function to hide a commit and its parents +* @param payload data payload to be passed to callback function +*/ +GIT_EXTERN(int) git_revwalk_add_hide_cb( + git_revwalk *walk, + git_revwalk_hide_cb hide_cb, + void *payload); + /** @} */ GIT_END_DECL #endif diff --git a/src/revwalk.c b/src/revwalk.c index f037ee692..4e2e0330a 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -81,6 +81,11 @@ static int process_commit(git_revwalk *walk, git_commit_list_node *commit, int h { int error; + if (!hide && walk->hide_cb) + { + hide = walk->hide_cb(&commit->oid, walk->hide_cb_payload); + } + if (hide && mark_uninteresting(commit) < 0) return -1; @@ -575,3 +580,26 @@ void git_revwalk_reset(git_revwalk *walk) git_vector_clear(&walk->twos); } +int git_revwalk_add_hide_cb( + git_revwalk *walk, + git_revwalk_hide_cb hide_cb, + void *payload) +{ + assert(walk); + + if (walk->walking) + git_revwalk_reset(walk); + + if (walk->hide_cb) + { + /* There is already a callback added */ + giterr_set(GITERR_INVALID, "There is already a callback added to hide commits in revision walker."); + return -1; + } + + walk->hide_cb = hide_cb; + walk->hide_cb_payload = payload; + + return 0; +} + diff --git a/src/revwalk.h b/src/revwalk.h index a0ce1ae86..a0654f3e5 100644 --- a/src/revwalk.h +++ b/src/revwalk.h @@ -39,6 +39,10 @@ struct git_revwalk { /* merge base calculation */ git_commit_list_node *one; git_vector twos; + + /* hide callback */ + git_revwalk_hide_cb hide_cb; + void *hide_cb_payload; }; git_commit_list_node *git_revwalk__commit_lookup(git_revwalk *walk, const git_oid *oid); From 3a666071d92562d028e2fba3ff12c49f3155c7f2 Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Mon, 10 Mar 2014 15:38:01 -0700 Subject: [PATCH 2/7] Unit Tests for hide_cb in revwalk --- include/git2/revwalk.h | 4 +- tests/revwalk/hidecb.c | 199 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 tests/revwalk/hidecb.c diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h index 7ab082752..af425c04d 100644 --- a/include/git2/revwalk.h +++ b/include/git2/revwalk.h @@ -263,7 +263,7 @@ GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk); /** * This is a callback function that user can provide to hide a -* commit and its parents. If the callback function returns true, +* commit and its parents. If the callback function returns non-zero value, * then this commit and its parents will be hidden. * * @param commit_id oid of Commit @@ -274,7 +274,7 @@ typedef int(*git_revwalk_hide_cb)( void *payload); /** -* Adds a callback function to hide a commit +* Adds a callback function to hide a commit and its parents * * @param walk the revision walker * @param hide_cb callback function to hide a commit and its parents diff --git a/tests/revwalk/hidecb.c b/tests/revwalk/hidecb.c new file mode 100644 index 000000000..b6747588e --- /dev/null +++ b/tests/revwalk/hidecb.c @@ -0,0 +1,199 @@ +#include "clar_libgit2.h" +/* +* a4a7dce [0] Merge branch 'master' into br2 +|\ +| * 9fd738e [1] a fourth commit +| * 4a202b3 [2] a third commit +* | c47800c [3] branch commit one +|/ +* 5b5b025 [5] another commit +* 8496071 [4] testing +*/ +static const char *commit_head = "a4a7dce85cf63874e984719f4fdd239f5145052f"; + +static const char *commit_strs[] = { + "a4a7dce85cf63874e984719f4fdd239f5145052f", /* 0 */ + "9fd738e8f7967c078dceed8190330fc8648ee56a", /* 1 */ + "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", /* 2 */ + "c47800c7266a2be04c571c04d5a6614691ea99bd", /* 3 */ + "8496071c1b46c854b31185ea97743be6a8774479", /* 4 */ + "5b5b025afb0b4c913b4c338a42934a3863bf3644", /* 5 */ +}; + +#define commit_count 6 + +static git_oid commit_ids[commit_count]; +static git_oid _head_id; +static git_repository *_repo; + + +void test_revwalk_hidecb__initialize(void) +{ + int i; + + cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); + cl_git_pass(git_oid_fromstr(&_head_id, commit_head)); + + for (i = 0; i < commit_count; i++) + { + cl_git_pass(git_oid_fromstr(&commit_ids[i], commit_strs[i])); + } + +} + +void test_revwalk_hidecb__cleanup(void) +{ + git_repository_free(_repo); + _repo = NULL; +} + +/* Hide all commits */ +static int hide_every_commit_cb(const git_oid *commit_id, void *data) +{ + return 1; +} + +/* Do not hide anything */ +static int hide_none_cb(const git_oid *commit_id, void *data) +{ + return 0; +} + +/* Hide some commits */ +static int hide_commit_cb(const git_oid *commit_id, void *data) +{ + if (0 == git_oid_cmp(commit_id, &commit_ids[3])) + return 1; + else + return 0; + +} + +/* In payload data, pointer to a commit id is passed */ +static int hide_commit_use_payload_cb(const git_oid *commit_id, void *data) +{ + git_oid *hide_commit_id = data; + if (0 == git_oid_cmp(commit_id, hide_commit_id)) + return 1; + else + return 0; +} + +void test_revwalk_hidecb__hide_all_cb(void) +{ + git_revwalk *walk; + git_oid id; + + cl_git_pass(git_revwalk_new(&walk, _repo)); + cl_git_pass(git_revwalk_add_hide_cb(walk, hide_every_commit_cb, NULL)); + cl_git_pass(git_revwalk_push(walk, &_head_id)); + + /* First call to git_revwalk_next should return GIT_ITEROVER */ + cl_assert_equal_i(GIT_ITEROVER, git_revwalk_next(&id, walk)); + + git_revwalk_free(walk); +} + + +void test_revwalk_hidecb__hide_none_cb(void) +{ + git_revwalk *walk; + int i, error; + git_oid id; + + cl_git_pass(git_revwalk_new(&walk, _repo)); + cl_git_pass(git_revwalk_add_hide_cb(walk, hide_none_cb, NULL)); + cl_git_pass(git_revwalk_push(walk, &_head_id)); + + /* It should return all 6 commits */ + i = 0; + while ((error = git_revwalk_next(&id, walk)) == 0) + i++; + + cl_assert_equal_i(i, 6); + cl_assert_equal_i(error, GIT_ITEROVER); + + git_revwalk_free(walk); +} + +void test_revwalk_hidecb__add_hide_cb_multiple_times(void) +{ + git_revwalk *walk; + + cl_git_pass(git_revwalk_new(&walk, _repo)); + cl_git_pass(git_revwalk_add_hide_cb(walk, hide_every_commit_cb, NULL)); + cl_git_fail(git_revwalk_add_hide_cb(walk, hide_every_commit_cb, NULL)); + + git_revwalk_free(walk); +} + +void test_revwalk_hidecb__add_hide_cb_during_walking(void) +{ + git_revwalk *walk; + git_oid id; + int error; + + cl_git_pass(git_revwalk_new(&walk, _repo)); + cl_git_pass(git_revwalk_push(walk, &_head_id)); + + /* Start walking without adding hide callback */ + cl_git_pass(git_revwalk_next(&id, walk)); + + /* Now add hide callback */ + cl_git_pass(git_revwalk_add_hide_cb(walk, hide_none_cb, NULL)); + + /* walk should be reset */ + error = git_revwalk_next(&id, walk); + cl_assert_equal_i(error, GIT_ITEROVER); + + git_revwalk_free(walk); +} + +void test_revwalk_hidecb__hide_some_commits(void) +{ + git_revwalk *walk; + git_oid id; + int i, error; + + cl_git_pass(git_revwalk_new(&walk, _repo)); + cl_git_pass(git_revwalk_push(walk, &_head_id)); + + /* Add hide callback */ + cl_git_pass(git_revwalk_add_hide_cb(walk, hide_commit_cb, NULL)); + + i = 0; + while ((error = git_revwalk_next(&id, walk)) == 0) { + cl_assert_equal_i(git_oid_cmp(&id, &commit_ids[i]), 0); + i++; + } + + cl_assert_equal_i(i, 3); + cl_assert_equal_i(error, GIT_ITEROVER); + + git_revwalk_free(walk); +} + +void test_revwalk_hidecb__test_payload(void) +{ + git_revwalk *walk; + git_oid id; + int i, error; + + cl_git_pass(git_revwalk_new(&walk, _repo)); + cl_git_pass(git_revwalk_push(walk, &_head_id)); + + /* Add hide callback, pass id of parent of initial commit as payload data */ + cl_git_pass(git_revwalk_add_hide_cb(walk, hide_commit_use_payload_cb, &commit_ids[5])); + + i = 0; + while ((error = git_revwalk_next(&id, walk)) == 0) { + cl_assert_equal_i(git_oid_cmp(&id, &commit_ids[i]), 0); + i++; + } + + /* walker should return four commits */ + cl_assert_equal_i(i, 4); + cl_assert_equal_i(error, GIT_ITEROVER); + + git_revwalk_free(walk); +} From 46e4d82d6f3e1630cacbd89af39ef3d2e9f20d09 Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Mon, 10 Mar 2014 16:21:56 -0700 Subject: [PATCH 3/7] Remove unused push_cb_data --- src/revwalk.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/revwalk.c b/src/revwalk.c index 4e2e0330a..edde661e6 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -183,11 +183,6 @@ static int push_ref(git_revwalk *walk, const char *refname, int hide, int from_g return push_commit(walk, &oid, hide, from_glob); } -struct push_cb_data { - git_revwalk *walk; - int hide; -}; - static int push_glob(git_revwalk *walk, const char *glob, int hide) { int error = 0; From 7ca1584b4771703bd9f9c3ad4335f6155b05450a Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Tue, 11 Mar 2014 11:49:19 -0700 Subject: [PATCH 4/7] Conforming to libgit2 coding style. --- .gitignore | 1 + CMakeLists.txt | 2 +- src/revwalk.c | 5 +---- tests/revwalk/hidecb.c | 5 ++--- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index d4e0454fa..a28d73866 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ .lock-wafbuild .waf* build/ +buildx64/ build-amiga/ tests/tmp/ msvc/Debug/ diff --git a/CMakeLists.txt b/CMakeLists.txt index cca2a120c..be3b53a8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,7 +221,7 @@ IF (MSVC) # /GF - String pooling # /MP - Parallel build - SET(CMAKE_C_FLAGS "/GF /MP /nologo ${CMAKE_C_FLAGS}") + SET(CMAKE_C_FLAGS "/GF /MP /wd4244 /wd4267 /nologo ${CMAKE_C_FLAGS}") IF (STDCALL) # /Gz - stdcall calling convention diff --git a/src/revwalk.c b/src/revwalk.c index edde661e6..f0109360b 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -82,9 +82,7 @@ static int process_commit(git_revwalk *walk, git_commit_list_node *commit, int h int error; if (!hide && walk->hide_cb) - { hide = walk->hide_cb(&commit->oid, walk->hide_cb_payload); - } if (hide && mark_uninteresting(commit) < 0) return -1; @@ -585,8 +583,7 @@ int git_revwalk_add_hide_cb( if (walk->walking) git_revwalk_reset(walk); - if (walk->hide_cb) - { + if (walk->hide_cb) { /* There is already a callback added */ giterr_set(GITERR_INVALID, "There is already a callback added to hide commits in revision walker."); return -1; diff --git a/tests/revwalk/hidecb.c b/tests/revwalk/hidecb.c index b6747588e..4c43f613b 100644 --- a/tests/revwalk/hidecb.c +++ b/tests/revwalk/hidecb.c @@ -35,9 +35,7 @@ void test_revwalk_hidecb__initialize(void) cl_git_pass(git_oid_fromstr(&_head_id, commit_head)); for (i = 0; i < commit_count; i++) - { cl_git_pass(git_oid_fromstr(&commit_ids[i], commit_strs[i])); - } } @@ -73,7 +71,7 @@ static int hide_commit_cb(const git_oid *commit_id, void *data) static int hide_commit_use_payload_cb(const git_oid *commit_id, void *data) { git_oid *hide_commit_id = data; - if (0 == git_oid_cmp(commit_id, hide_commit_id)) + if (git_oid_cmp(commit_id, hide_commit_id) == 0) return 1; else return 0; @@ -197,3 +195,4 @@ void test_revwalk_hidecb__test_payload(void) git_revwalk_free(walk); } + From 169fb81d8780532ffe575b5dfbf29a1027dfe25d Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Tue, 11 Mar 2014 11:56:26 -0700 Subject: [PATCH 5/7] Undoing local change done for building on x64 --- .gitignore | 1 - CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a28d73866..d4e0454fa 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,6 @@ .lock-wafbuild .waf* build/ -buildx64/ build-amiga/ tests/tmp/ msvc/Debug/ diff --git a/CMakeLists.txt b/CMakeLists.txt index be3b53a8f..cca2a120c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,7 +221,7 @@ IF (MSVC) # /GF - String pooling # /MP - Parallel build - SET(CMAKE_C_FLAGS "/GF /MP /wd4244 /wd4267 /nologo ${CMAKE_C_FLAGS}") + SET(CMAKE_C_FLAGS "/GF /MP /nologo ${CMAKE_C_FLAGS}") IF (STDCALL) # /Gz - stdcall calling convention From 892b7c9fef3aa48574b784e48a8747e77e83865b Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Tue, 11 Mar 2014 12:13:29 -0700 Subject: [PATCH 6/7] Correcting format of comments in header file --- include/git2/revwalk.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h index af425c04d..1bd6186f3 100644 --- a/include/git2/revwalk.h +++ b/include/git2/revwalk.h @@ -262,24 +262,24 @@ GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk); GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk); /** -* This is a callback function that user can provide to hide a -* commit and its parents. If the callback function returns non-zero value, -* then this commit and its parents will be hidden. -* -* @param commit_id oid of Commit -* @param payload User-specified pointer to data to be passed as data payload -*/ + * This is a callback function that user can provide to hide a + * commit and its parents. If the callback function returns non-zero value, + * then this commit and its parents will be hidden. + * + * @param commit_id oid of Commit + * @param payload User-specified pointer to data to be passed as data payload + */ typedef int(*git_revwalk_hide_cb)( const git_oid *commit_id, void *payload); /** -* Adds a callback function to hide a commit and its parents -* -* @param walk the revision walker -* @param hide_cb callback function to hide a commit and its parents -* @param payload data payload to be passed to callback function -*/ + * Adds a callback function to hide a commit and its parents + * + * @param walk the revision walker + * @param hide_cb callback function to hide a commit and its parents + * @param payload data payload to be passed to callback function + */ GIT_EXTERN(int) git_revwalk_add_hide_cb( git_revwalk *walk, git_revwalk_hide_cb hide_cb, From 34ffe22344d32d1574dc33d3c3d20556fdb152a7 Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Mon, 24 Mar 2014 11:02:02 -0700 Subject: [PATCH 7/7] Modified test for revwalk_hidecb --- tests/revwalk/hidecb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/revwalk/hidecb.c b/tests/revwalk/hidecb.c index 4c43f613b..c13a17747 100644 --- a/tests/revwalk/hidecb.c +++ b/tests/revwalk/hidecb.c @@ -60,7 +60,7 @@ static int hide_none_cb(const git_oid *commit_id, void *data) /* Hide some commits */ static int hide_commit_cb(const git_oid *commit_id, void *data) { - if (0 == git_oid_cmp(commit_id, &commit_ids[3])) + if (0 == git_oid_cmp(commit_id, &commit_ids[5])) return 1; else return 0; @@ -165,7 +165,7 @@ void test_revwalk_hidecb__hide_some_commits(void) i++; } - cl_assert_equal_i(i, 3); + cl_assert_equal_i(i, 4); cl_assert_equal_i(error, GIT_ITEROVER); git_revwalk_free(walk);