diff options
| author | Vicent Marti <tanoku@gmail.com> | 2014-06-20 14:42:16 +0200 |
|---|---|---|
| committer | Vicent Marti <tanoku@gmail.com> | 2014-06-20 14:42:16 +0200 |
| commit | 28f087c8642ff9c8dd6964e101e6d8539db6281a (patch) | |
| tree | 3518d1bf420e92c964bed03074575d8a1db88654 /tests/refs | |
| parent | 4b0a36e881506a02b43a4ae3c19c93c919b36eeb (diff) | |
| parent | 1589aa0c4d48fb130d8a5db28c45cd3d173cde6d (diff) | |
| download | libgit2-28f087c8642ff9c8dd6964e101e6d8539db6281a.tar.gz | |
libgit2 v0.21.0v0.21.0
Diffstat (limited to 'tests/refs')
| -rw-r--r-- | tests/refs/branches/create.c | 152 | ||||
| -rw-r--r-- | tests/refs/branches/delete.c | 37 | ||||
| -rw-r--r-- | tests/refs/branches/ishead.c | 30 | ||||
| -rw-r--r-- | tests/refs/branches/iterator.c | 8 | ||||
| -rw-r--r-- | tests/refs/branches/move.c | 136 | ||||
| -rw-r--r-- | tests/refs/branches/remote.c | 39 | ||||
| -rw-r--r-- | tests/refs/branches/upstream.c | 2 | ||||
| -rw-r--r-- | tests/refs/branches/upstreamname.c | 10 | ||||
| -rw-r--r-- | tests/refs/crashes.c | 2 | ||||
| -rw-r--r-- | tests/refs/create.c | 16 | ||||
| -rw-r--r-- | tests/refs/createwithlog.c | 51 | ||||
| -rw-r--r-- | tests/refs/delete.c | 16 | ||||
| -rw-r--r-- | tests/refs/foreachglob.c | 6 | ||||
| -rw-r--r-- | tests/refs/iterator.c | 160 | ||||
| -rw-r--r-- | tests/refs/overwrite.c | 26 | ||||
| -rw-r--r-- | tests/refs/pack.c | 4 | ||||
| -rw-r--r-- | tests/refs/races.c | 152 | ||||
| -rw-r--r-- | tests/refs/read.c | 15 | ||||
| -rw-r--r-- | tests/refs/reflog/reflog.c | 199 | ||||
| -rw-r--r-- | tests/refs/rename.c | 55 | ||||
| -rw-r--r-- | tests/refs/revparse.c | 11 | ||||
| -rw-r--r-- | tests/refs/settargetwithlog.c | 55 | ||||
| -rw-r--r-- | tests/refs/setter.c | 10 | ||||
| -rw-r--r-- | tests/refs/unicode.c | 2 | ||||
| -rw-r--r-- | tests/refs/update.c | 2 |
25 files changed, 990 insertions, 206 deletions
diff --git a/tests/refs/branches/create.c b/tests/refs/branches/create.c index 693a592a3..3a4f33b6e 100644 --- a/tests/refs/branches/create.c +++ b/tests/refs/branches/create.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "refs.h" +#include "path.h" static git_repository *repo; static git_commit *target; @@ -7,10 +8,9 @@ static git_reference *branch; void test_refs_branches_create__initialize(void) { - cl_fixture_sandbox("testrepo.git"); - cl_git_pass(git_repository_open(&repo, "testrepo.git")); - + repo = cl_git_sandbox_init("testrepo.git"); branch = NULL; + target = NULL; } void test_refs_branches_create__cleanup(void) @@ -21,23 +21,22 @@ void test_refs_branches_create__cleanup(void) git_commit_free(target); target = NULL; - git_repository_free(repo); + cl_git_sandbox_cleanup(); repo = NULL; - - cl_fixture_cleanup("testrepo.git"); } static void retrieve_target_from_oid(git_commit **out, git_repository *repo, const char *sha) { - git_oid oid; + git_object *obj; - cl_git_pass(git_oid_fromstr(&oid, sha)); - cl_git_pass(git_commit_lookup(out, repo, &oid)); + cl_git_pass(git_revparse_single(&obj, repo, sha)); + cl_git_pass(git_commit_lookup(out, repo, git_object_id(obj))); + git_object_free(obj); } static void retrieve_known_commit(git_commit **commit, git_repository *repo) { - retrieve_target_from_oid(commit, repo, "e90810b8df3e80c413d903f631643c716887138d"); + retrieve_target_from_oid(commit, repo, "e90810b8df3"); } #define NEW_BRANCH_NAME "new-branch-on-the-block" @@ -46,7 +45,7 @@ void test_refs_branches_create__can_create_a_local_branch(void) { retrieve_known_commit(&target, repo); - cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, 0)); + cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); } @@ -54,23 +53,146 @@ void test_refs_branches_create__can_not_create_a_branch_if_its_name_collide_with { retrieve_known_commit(&target, repo); - cl_assert_equal_i(GIT_EEXISTS, git_branch_create(&branch, repo, "br2", target, 0)); + cl_assert_equal_i(GIT_EEXISTS, git_branch_create(&branch, repo, "br2", target, 0, NULL, NULL)); } void test_refs_branches_create__can_force_create_over_an_existing_branch(void) { retrieve_known_commit(&target, repo); - cl_git_pass(git_branch_create(&branch, repo, "br2", target, 1)); + cl_git_pass(git_branch_create(&branch, repo, "br2", target, 1, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); cl_assert_equal_s("refs/heads/br2", git_reference_name(branch)); } +void test_refs_branches_create__cannot_force_create_over_current_branch(void) +{ + const git_oid *oid; + git_reference *branch2; + retrieve_known_commit(&target, repo); + + cl_git_pass(git_branch_lookup(&branch2, repo, "master", GIT_BRANCH_LOCAL)); + cl_assert_equal_s("refs/heads/master", git_reference_name(branch2)); + cl_assert_equal_i(true, git_branch_is_head(branch2)); + oid = git_reference_target(branch2); + + cl_git_fail_with(-1, git_branch_create(&branch, repo, "master", target, 1, NULL, NULL)); + branch = NULL; + cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL)); + cl_assert_equal_s("refs/heads/master", git_reference_name(branch)); + cl_git_pass(git_oid_cmp(git_reference_target(branch), oid)); + git_reference_free(branch2); +} void test_refs_branches_create__creating_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void) { retrieve_known_commit(&target, repo); cl_assert_equal_i(GIT_EINVALIDSPEC, - git_branch_create(&branch, repo, "inv@{id", target, 0)); -}
\ No newline at end of file + git_branch_create(&branch, repo, "inv@{id", target, 0, NULL, NULL)); +} + +void test_refs_branches_create__creation_creates_new_reflog(void) +{ + git_reflog *log; + const git_reflog_entry *entry; + git_signature *sig; + + cl_git_pass(git_signature_now(&sig, "me", "foo@example.com")); + + retrieve_known_commit(&target, repo); + cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false, sig, "create!")); + cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); + + cl_assert_equal_i(1, git_reflog_entrycount(log)); + entry = git_reflog_entry_byindex(log, 0); + cl_assert_equal_s("create!", git_reflog_entry_message(entry)); + cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email); + + git_reflog_free(log); + git_signature_free(sig); +} + +void test_refs_branches_create__default_reflog_message(void) +{ + git_reflog *log; + const git_reflog_entry *entry; + git_signature *sig; + git_config *cfg; + + cl_git_pass(git_repository_config(&cfg, repo)); + cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar")); + cl_git_pass(git_config_set_string(cfg, "user.email", "foo@example.com")); + git_config_free(cfg); + + cl_git_pass(git_signature_default(&sig, repo)); + + retrieve_known_commit(&target, repo); + cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false, NULL, NULL)); + cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME)); + + entry = git_reflog_entry_byindex(log, 0); + cl_assert_equal_s("Branch: created", git_reflog_entry_message(entry)); + cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); + + git_reflog_free(log); + git_signature_free(sig); +} + +static void assert_branch_matches_name( + const char *expected, const char *lookup_as) +{ + git_reference *ref; + git_buf b = GIT_BUF_INIT; + + cl_git_pass(git_branch_lookup(&ref, repo, lookup_as, GIT_BRANCH_LOCAL)); + + cl_git_pass(git_buf_sets(&b, "refs/heads/")); + cl_git_pass(git_buf_puts(&b, expected)); + cl_assert_equal_s(b.ptr, git_reference_name(ref)); + + cl_git_pass( + git_oid_cmp(git_reference_target(ref), git_commit_id(target))); + + git_reference_free(ref); + git_buf_free(&b); +} + +void test_refs_branches_create__can_create_branch_with_unicode(void) +{ + const char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"; + const char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; + const char *emoji = "\xF0\x9F\x8D\xB7"; + const char *names[] = { nfc, nfd, emoji }; + const char *alt[] = { nfd, nfc, NULL }; + const char *expected[] = { nfc, nfd, emoji }; + unsigned int i; + bool fs_decompose_unicode = + git_path_does_fs_decompose_unicode(git_repository_path(repo)); + + retrieve_known_commit(&target, repo); + + if (cl_repo_get_bool(repo, "core.precomposeunicode")) + expected[1] = nfc; + /* test decomp. because not all Mac filesystems decompose unicode */ + else if (fs_decompose_unicode) + expected[0] = nfd; + + for (i = 0; i < ARRAY_SIZE(names); ++i) { + const char *name; + cl_git_pass(git_branch_create( + &branch, repo, names[i], target, 0, NULL, NULL)); + cl_git_pass(git_oid_cmp( + git_reference_target(branch), git_commit_id(target))); + + cl_git_pass(git_branch_name(&name, branch)); + cl_assert_equal_s(expected[i], name); + assert_branch_matches_name(expected[i], names[i]); + if (fs_decompose_unicode && alt[i]) + assert_branch_matches_name(expected[i], alt[i]); + + cl_git_pass(git_branch_delete(branch)); + git_reference_free(branch); + branch = NULL; + } +} diff --git a/tests/refs/branches/delete.c b/tests/refs/branches/delete.c index de90cb734..e3199e230 100644 --- a/tests/refs/branches/delete.c +++ b/tests/refs/branches/delete.c @@ -10,11 +10,10 @@ void test_refs_branches_delete__initialize(void) { git_oid id; - cl_fixture_sandbox("testrepo.git"); - cl_git_pass(git_repository_open(&repo, "testrepo.git")); + repo = cl_git_sandbox_init("testrepo.git"); cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0)); + cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL, NULL)); } void test_refs_branches_delete__cleanup(void) @@ -22,10 +21,8 @@ void test_refs_branches_delete__cleanup(void) git_reference_free(fake_remote); fake_remote = NULL; - git_repository_free(repo); + cl_git_sandbox_cleanup(); repo = NULL; - - cl_fixture_cleanup("testrepo.git"); } void test_refs_branches_delete__can_not_delete_a_branch_pointed_at_by_HEAD(void) @@ -78,7 +75,7 @@ void test_refs_branches_delete__can_delete_a_branch_pointed_at_by_detached_HEAD( git_reference_free(head); /* Detach HEAD and make it target the commit that "master" points to */ - git_repository_detach_head(repo); + git_repository_detach_head(repo, NULL, NULL); cl_git_pass(git_branch_lookup(&branch, repo, "master", GIT_BRANCH_LOCAL)); cl_git_pass(git_branch_delete(branch)); @@ -115,3 +112,29 @@ void test_refs_branches_delete__deleting_a_branch_removes_related_configuration_ assert_config_entry_existence(repo, "branch.track-local.remote", false); assert_config_entry_existence(repo, "branch.track-local.merge", false); } + +void test_refs_branches_delete__removes_reflog(void) +{ + git_reference *branch; + git_reflog *log; + git_oid oidzero = {{0}}; + git_signature *sig; + + /* Ensure the reflog has at least one entry */ + cl_git_pass(git_signature_now(&sig, "Me", "user@example.com")); + cl_git_pass(git_reflog_read(&log, repo, "refs/heads/track-local")); + cl_git_pass(git_reflog_append(log, &oidzero, sig, "message")); + cl_assert(git_reflog_entrycount(log) > 0); + git_signature_free(sig); + git_reflog_free(log); + + cl_git_pass(git_branch_lookup(&branch, repo, "track-local", GIT_BRANCH_LOCAL)); + cl_git_pass(git_branch_delete(branch)); + git_reference_free(branch); + + /* Reading a nonexistant reflog creates it, but it should be empty */ + cl_git_pass(git_reflog_read(&log, repo, "refs/heads/track-local")); + cl_assert_equal_i(0, git_reflog_entrycount(log)); + git_reflog_free(log); +} + diff --git a/tests/refs/branches/ishead.c b/tests/refs/branches/ishead.c index b1ad09c3e..d16a79652 100644 --- a/tests/refs/branches/ishead.c +++ b/tests/refs/branches/ishead.c @@ -7,7 +7,8 @@ static git_reference *branch; void test_refs_branches_ishead__initialize(void) { - cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + repo = cl_git_sandbox_init("testrepo.git"); + branch = NULL; } void test_refs_branches_ishead__cleanup(void) @@ -15,7 +16,7 @@ void test_refs_branches_ishead__cleanup(void) git_reference_free(branch); branch = NULL; - git_repository_free(repo); + cl_git_sandbox_cleanup(); repo = NULL; } @@ -28,34 +29,20 @@ void test_refs_branches_ishead__can_tell_if_a_branch_is_pointed_at_by_HEAD(void) void test_refs_branches_ishead__can_properly_handle_unborn_HEAD(void) { - git_repository_free(repo); - - repo = cl_git_sandbox_init("testrepo.git"); - make_head_unborn(repo, NON_EXISTING_HEAD); cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master")); cl_assert_equal_i(false, git_branch_is_head(branch)); - - cl_git_sandbox_cleanup(); - repo = NULL; } void test_refs_branches_ishead__can_properly_handle_missing_HEAD(void) { - git_repository_free(repo); - - repo = cl_git_sandbox_init("testrepo.git"); - delete_head(repo); cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master")); cl_assert_equal_i(false, git_branch_is_head(branch)); - - cl_git_sandbox_cleanup(); - repo = NULL; } void test_refs_branches_ishead__can_tell_if_a_branch_is_not_pointed_at_by_HEAD(void) @@ -95,12 +82,9 @@ void test_refs_branches_ishead__only_direct_references_are_considered(void) { git_reference *linked, *super, *head; - git_repository_free(repo); - repo = cl_git_sandbox_init("testrepo.git"); - - cl_git_pass(git_reference_symbolic_create(&linked, repo, "refs/heads/linked", "refs/heads/master", 0)); - cl_git_pass(git_reference_symbolic_create(&super, repo, "refs/heads/super", "refs/heads/linked", 0)); - cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/heads/super", 1)); + cl_git_pass(git_reference_symbolic_create(&linked, repo, "refs/heads/linked", "refs/heads/master", 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&super, repo, "refs/heads/super", "refs/heads/linked", 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&head, repo, GIT_HEAD_FILE, "refs/heads/super", 1, NULL, NULL)); cl_assert_equal_i(false, git_branch_is_head(linked)); cl_assert_equal_i(false, git_branch_is_head(super)); @@ -111,6 +95,4 @@ void test_refs_branches_ishead__only_direct_references_are_considered(void) git_reference_free(linked); git_reference_free(super); git_reference_free(head); - cl_git_sandbox_cleanup(); - repo = NULL; } diff --git a/tests/refs/branches/iterator.c b/tests/refs/branches/iterator.c index 904c6a146..76b35a7d6 100644 --- a/tests/refs/branches/iterator.c +++ b/tests/refs/branches/iterator.c @@ -12,7 +12,7 @@ void test_refs_branches_iterator__initialize(void) cl_git_pass(git_repository_open(&repo, "testrepo.git")); cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0)); + cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL, NULL)); } void test_refs_branches_iterator__cleanup(void) @@ -48,7 +48,7 @@ static void assert_retrieval(unsigned int flags, unsigned int expected_count) void test_refs_branches_iterator__retrieve_all_branches(void) { - assert_retrieval(GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE, 14); + assert_retrieval(GIT_BRANCH_ALL, 14); } void test_refs_branches_iterator__retrieve_remote_branches(void) @@ -113,7 +113,7 @@ void test_refs_branches_iterator__retrieve_remote_symbolic_HEAD_when_present(voi }; git_reference_free(fake_remote); - cl_git_pass(git_reference_symbolic_create(&fake_remote, repo, "refs/remotes/nulltoken/HEAD", "refs/remotes/nulltoken/master", 0)); + cl_git_pass(git_reference_symbolic_create(&fake_remote, repo, "refs/remotes/nulltoken/HEAD", "refs/remotes/nulltoken/master", 0, NULL, NULL)); assert_retrieval(GIT_BRANCH_REMOTE, 3); @@ -139,7 +139,7 @@ void test_refs_branches_iterator__mix_of_packed_and_loose(void) r2 = cl_git_sandbox_init("testrepo2"); - cl_git_pass(git_branch_iterator_new(&iter, r2, GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE)); + cl_git_pass(git_branch_iterator_new(&iter, r2, GIT_BRANCH_ALL)); contains_branches(exp, iter); git_branch_iterator_free(iter); diff --git a/tests/refs/branches/move.c b/tests/refs/branches/move.c index ecf14e006..f136b00d6 100644 --- a/tests/refs/branches/move.c +++ b/tests/refs/branches/move.c @@ -22,7 +22,7 @@ void test_refs_branches_move__can_move_a_local_branch(void) cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2")); - cl_git_pass(git_branch_move(&new_ref, original_ref, NEW_BRANCH_NAME, 0)); + cl_git_pass(git_branch_move(&new_ref, original_ref, NEW_BRANCH_NAME, 0, NULL, NULL)); cl_assert_equal_s(GIT_REFS_HEADS_DIR NEW_BRANCH_NAME, git_reference_name(new_ref)); git_reference_free(original_ref); @@ -36,11 +36,11 @@ void test_refs_branches_move__can_move_a_local_branch_to_a_different_namespace(v cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2")); /* Downward */ - cl_git_pass(git_branch_move(&new_ref, original_ref, "somewhere/" NEW_BRANCH_NAME, 0)); + cl_git_pass(git_branch_move(&new_ref, original_ref, "somewhere/" NEW_BRANCH_NAME, 0, NULL, NULL)); git_reference_free(original_ref); /* Upward */ - cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0)); + cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0, NULL, NULL)); git_reference_free(new_ref); git_reference_free(newer_ref); @@ -53,11 +53,11 @@ void test_refs_branches_move__can_move_a_local_branch_to_a_partially_colliding_n cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2")); /* Downward */ - cl_git_pass(git_branch_move(&new_ref, original_ref, "br2/" NEW_BRANCH_NAME, 0)); + cl_git_pass(git_branch_move(&new_ref, original_ref, "br2/" NEW_BRANCH_NAME, 0, NULL, NULL)); git_reference_free(original_ref); /* Upward */ - cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0)); + cl_git_pass(git_branch_move(&newer_ref, new_ref, "br2", 0, NULL, NULL)); git_reference_free(new_ref); git_reference_free(newer_ref); @@ -66,12 +66,54 @@ void test_refs_branches_move__can_move_a_local_branch_to_a_partially_colliding_n void test_refs_branches_move__can_not_move_a_branch_if_its_destination_name_collide_with_an_existing_one(void) { git_reference *original_ref, *new_ref; + git_config *config; + const git_config_entry *ce; + char *original_remote, *original_merge; + + cl_git_pass(git_repository_config(&config, repo)); + + cl_git_pass(git_config_get_entry(&ce, config, "branch.master.remote")); + original_remote = strdup(ce->value); + cl_git_pass(git_config_get_entry(&ce, config, "branch.master.merge")); + original_merge = strdup(ce->value); + cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2")); - cl_assert_equal_i(GIT_EEXISTS, git_branch_move(&new_ref, original_ref, "master", 0)); + cl_assert_equal_i(GIT_EEXISTS, + git_branch_move(&new_ref, original_ref, "master", 0, NULL, NULL)); + + cl_assert(giterr_last()->message != NULL); + cl_git_pass(git_config_get_entry(&ce, config, "branch.master.remote")); + cl_assert_equal_s(original_remote, ce->value); + cl_git_pass(git_config_get_entry(&ce, config, "branch.master.merge")); + cl_assert_equal_s(original_merge, ce->value); + + + cl_assert_equal_i(GIT_EEXISTS, + git_branch_move(&new_ref, original_ref, "cannot-fetch", 0, NULL, NULL)); + cl_assert(giterr_last()->message != NULL); + cl_git_pass(git_config_get_entry(&ce, config, "branch.master.remote")); + cl_assert_equal_s(original_remote, ce->value); + cl_git_pass(git_config_get_entry(&ce, config, "branch.master.merge")); + cl_assert_equal_s(original_merge, ce->value); + + git_reference_free(original_ref); + cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/track-local")); + + cl_assert_equal_i(GIT_EEXISTS, + git_branch_move(&new_ref, original_ref, "master", 0, NULL, NULL)); + + cl_assert(giterr_last()->message != NULL); + cl_git_pass(git_config_get_entry(&ce, config, "branch.master.remote")); + cl_assert_equal_s(original_remote, ce->value); + cl_git_pass(git_config_get_entry(&ce, config, "branch.master.merge")); + cl_assert_equal_s(original_merge, ce->value); + + free(original_remote); free(original_merge); git_reference_free(original_ref); + git_config_free(config); } void test_refs_branches_move__moving_a_branch_with_an_invalid_name_returns_EINVALIDSPEC(void) @@ -80,7 +122,7 @@ void test_refs_branches_move__moving_a_branch_with_an_invalid_name_returns_EINVA cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2")); - cl_assert_equal_i(GIT_EINVALIDSPEC, git_branch_move(&new_ref, original_ref, "Inv@{id", 0)); + cl_assert_equal_i(GIT_EINVALIDSPEC, git_branch_move(&new_ref, original_ref, "Inv@{id", 0, NULL, NULL)); git_reference_free(original_ref); } @@ -90,7 +132,7 @@ void test_refs_branches_move__can_not_move_a_non_branch(void) git_reference *tag, *new_ref; cl_git_pass(git_reference_lookup(&tag, repo, "refs/tags/e90810b")); - cl_git_fail(git_branch_move(&new_ref, tag, NEW_BRANCH_NAME, 0)); + cl_git_fail(git_branch_move(&new_ref, tag, NEW_BRANCH_NAME, 0, NULL, NULL)); git_reference_free(tag); } @@ -101,7 +143,7 @@ void test_refs_branches_move__can_force_move_over_an_existing_branch(void) cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2")); - cl_git_pass(git_branch_move(&new_ref, original_ref, "master", 1)); + cl_git_pass(git_branch_move(&new_ref, original_ref, "master", 1, NULL, NULL)); git_reference_free(original_ref); git_reference_free(new_ref); @@ -119,7 +161,7 @@ void test_refs_branches_move__moving_a_branch_moves_related_configuration_data(v assert_config_entry_existence(repo, "branch.moved.remote", false); assert_config_entry_existence(repo, "branch.moved.merge", false); - cl_git_pass(git_branch_move(&new_branch, branch, "moved", 0)); + cl_git_pass(git_branch_move(&new_branch, branch, "moved", 0, NULL, NULL)); git_reference_free(branch); assert_config_entry_existence(repo, "branch.track-local.remote", false); @@ -136,7 +178,7 @@ void test_refs_branches_move__moving_the_branch_pointed_at_by_HEAD_updates_HEAD( git_reference *new_branch; cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master")); - cl_git_pass(git_branch_move(&new_branch, branch, "master2", 0)); + cl_git_pass(git_branch_move(&new_branch, branch, "master2", 0, NULL, NULL)); git_reference_free(branch); git_reference_free(new_branch); @@ -144,3 +186,75 @@ void test_refs_branches_move__moving_the_branch_pointed_at_by_HEAD_updates_HEAD( cl_assert_equal_s("refs/heads/master2", git_reference_name(branch)); git_reference_free(branch); } + +void test_refs_branches_move__updates_the_reflog(void) +{ + git_reference *branch; + git_reference *new_branch; + git_reflog *log; + const git_reflog_entry *entry; + git_signature *sig; + + cl_git_pass(git_signature_now(&sig, "me", "foo@example.com")); + + cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master")); + cl_git_pass(git_branch_move(&new_branch, branch, "master2", 0, sig, "message")); + + cl_git_pass(git_reflog_read(&log, repo, git_reference_name(new_branch))); + entry = git_reflog_entry_byindex(log, 0); + cl_assert_equal_s("message", git_reflog_entry_message(entry)); + cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email); + + git_reference_free(branch); + git_reference_free(new_branch); + git_reflog_free(log); + git_signature_free(sig); +} + +void test_refs_branches_move__default_reflog_message(void) +{ + git_reference *branch; + git_reference *new_branch; + git_reflog *log; + const git_reflog_entry *entry; + git_signature *sig; + git_config *cfg; + + cl_git_pass(git_repository_config(&cfg, repo)); + cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar")); + cl_git_pass(git_config_set_string(cfg, "user.email", "foo@example.com")); + git_config_free(cfg); + + cl_git_pass(git_signature_default(&sig, repo)); + + cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master")); + cl_git_pass(git_branch_move(&new_branch, branch, "master2", 0, NULL, NULL)); + + cl_git_pass(git_reflog_read(&log, repo, git_reference_name(new_branch))); + entry = git_reflog_entry_byindex(log, 0); + cl_assert_equal_s("Branch: renamed refs/heads/master to refs/heads/master2", + git_reflog_entry_message(entry)); + cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email); + + git_reference_free(branch); + git_reference_free(new_branch); + git_reflog_free(log); + git_signature_free(sig); +} + +void test_refs_branches_move__can_move_with_unicode(void) +{ + git_reference *original_ref, *new_ref; + const char *new_branch_name = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; + + cl_git_pass(git_reference_lookup(&original_ref, repo, "refs/heads/br2")); + cl_git_pass(git_branch_move(&new_ref, original_ref, new_branch_name, 0, NULL, NULL)); + + if (cl_repo_get_bool(repo, "core.precomposeunicode")) + cl_assert_equal_s(GIT_REFS_HEADS_DIR "\xC3\x85\x73\x74\x72\xC3\xB6\x6D", git_reference_name(new_ref)); + else + cl_assert_equal_s(GIT_REFS_HEADS_DIR "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D", git_reference_name(new_ref)); + + git_reference_free(original_ref); + git_reference_free(new_ref); +} diff --git a/tests/refs/branches/remote.c b/tests/refs/branches/remote.c index c110adb33..bac088454 100644 --- a/tests/refs/branches/remote.c +++ b/tests/refs/branches/remote.c @@ -21,53 +21,40 @@ void test_refs_branches_remote__cleanup(void) void test_refs_branches_remote__can_get_remote_for_branch(void) { - char remotename[1024] = {0}; + git_buf remotename = {0}; - cl_assert_equal_i(expected_remote_name_length, - git_branch_remote_name(NULL, 0, g_repo, remote_tracking_branch_name)); + cl_git_pass(git_branch_remote_name(&remotename, g_repo, remote_tracking_branch_name)); - cl_assert_equal_i(expected_remote_name_length, - git_branch_remote_name(remotename, expected_remote_name_length, g_repo, - remote_tracking_branch_name)); - - cl_assert_equal_s("test", remotename); -} - -void test_refs_branches_remote__insufficient_buffer_returns_error(void) -{ - char remotename[1024] = {0}; - - cl_assert_equal_i(expected_remote_name_length, - git_branch_remote_name(NULL, 0, g_repo, remote_tracking_branch_name)); - - cl_git_fail_with(git_branch_remote_name(remotename, - expected_remote_name_length - 1, g_repo, remote_tracking_branch_name), - expected_remote_name_length); + cl_assert_equal_s("test", remotename.ptr); + git_buf_free(&remotename); } void test_refs_branches_remote__no_matching_remote_returns_error(void) { const char *unknown = "refs/remotes/nonexistent/master"; + git_buf buf; giterr_clear(); - cl_git_fail_with(git_branch_remote_name( - NULL, 0, g_repo, unknown), GIT_ENOTFOUND); + memset(&buf, 0, sizeof(git_buf)); + cl_git_fail_with(git_branch_remote_name(&buf, g_repo, unknown), GIT_ENOTFOUND); cl_assert(giterr_last() != NULL); } void test_refs_branches_remote__local_remote_returns_error(void) { const char *local = "refs/heads/master"; + git_buf buf; giterr_clear(); - cl_git_fail_with(git_branch_remote_name( - NULL, 0, g_repo, local), GIT_ERROR); + memset(&buf, 0, sizeof(git_buf)); + cl_git_fail_with(git_branch_remote_name(&buf, g_repo, local), GIT_ERROR); cl_assert(giterr_last() != NULL); } void test_refs_branches_remote__ambiguous_remote_returns_error(void) { git_remote *remote; + git_buf buf; /* Create the remote */ cl_git_pass(git_remote_create(&remote, g_repo, "addtest", "http://github.com/libgit2/libgit2")); @@ -80,7 +67,7 @@ void test_refs_branches_remote__ambiguous_remote_returns_error(void) git_remote_free(remote); giterr_clear(); - cl_git_fail_with(git_branch_remote_name(NULL, 0, g_repo, - remote_tracking_branch_name), GIT_EAMBIGUOUS); + memset(&buf, 0, sizeof(git_buf)); + cl_git_fail_with(git_branch_remote_name(&buf, g_repo, remote_tracking_branch_name), GIT_EAMBIGUOUS); cl_assert(giterr_last() != NULL); } diff --git a/tests/refs/branches/upstream.c b/tests/refs/branches/upstream.c index 69e55a0c5..ce3569813 100644 --- a/tests/refs/branches/upstream.c +++ b/tests/refs/branches/upstream.c @@ -66,7 +66,7 @@ static void assert_merge_and_or_remote_key_missing(git_repository *repository, c git_reference *branch; cl_assert_equal_i(GIT_OBJ_COMMIT, git_object_type((git_object*)target)); - cl_git_pass(git_branch_create(&branch, repository, entry_name, (git_commit*)target, 0)); + cl_git_pass(git_branch_create(&branch, repository, entry_name, (git_commit*)target, 0, NULL, NULL)); cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch)); diff --git a/tests/refs/branches/upstreamname.c b/tests/refs/branches/upstreamname.c index f05607d44..d30002e08 100644 --- a/tests/refs/branches/upstreamname.c +++ b/tests/refs/branches/upstreamname.c @@ -21,7 +21,7 @@ void test_refs_branches_upstreamname__cleanup(void) void test_refs_branches_upstreamname__can_retrieve_the_remote_tracking_reference_name_of_a_local_branch(void) { - cl_git_pass(git_branch_upstream__name( + cl_git_pass(git_branch_upstream_name( &upstream_name, repo, "refs/heads/master")); cl_assert_equal_s("refs/remotes/test/master", git_buf_cstr(&upstream_name)); @@ -29,14 +29,8 @@ void test_refs_branches_upstreamname__can_retrieve_the_remote_tracking_reference void test_refs_branches_upstreamname__can_retrieve_the_local_upstream_reference_name_of_a_local_branch(void) { - cl_git_pass(git_branch_upstream__name( + cl_git_pass(git_branch_upstream_name( &upstream_name, repo, "refs/heads/track-local")); cl_assert_equal_s("refs/heads/master", git_buf_cstr(&upstream_name)); } - -void test_refs_branches_upstreamname__can_return_the_size_of_thelocal_upstream_reference_name_of_a_local_branch(void) -{ - cl_assert_equal_i((int)strlen("refs/heads/master") + 1, - git_branch_upstream_name(NULL, 0, repo, "refs/heads/track-local")); -} diff --git a/tests/refs/crashes.c b/tests/refs/crashes.c index 5a1885a7a..03082d71e 100644 --- a/tests/refs/crashes.c +++ b/tests/refs/crashes.c @@ -7,7 +7,7 @@ void test_refs_crashes__double_free(void) const char *REFNAME = "refs/heads/xxx"; cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); - cl_git_pass(git_reference_symbolic_create(&ref, repo, REFNAME, "refs/heads/master", 0)); + cl_git_pass(git_reference_symbolic_create(&ref, repo, REFNAME, "refs/heads/master", 0, NULL, NULL)); cl_git_pass(git_reference_lookup(&ref2, repo, REFNAME)); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); diff --git a/tests/refs/create.c b/tests/refs/create.c index 85ff05aa9..50b8e84f8 100644 --- a/tests/refs/create.c +++ b/tests/refs/create.c @@ -32,7 +32,7 @@ void test_refs_create__symbolic(void) git_oid_fromstr(&id, current_master_tip); /* Create and write the new symbolic reference */ - cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0)); + cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL, NULL)); /* Ensure the reference can be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker)); @@ -73,7 +73,7 @@ void test_refs_create__deep_symbolic(void) git_oid_fromstr(&id, current_master_tip); - cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0)); + cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL, NULL)); cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker)); cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref)); cl_assert(git_oid_cmp(&id, git_reference_target(resolved_ref)) == 0); @@ -95,7 +95,7 @@ void test_refs_create__oid(void) git_oid_fromstr(&id, current_master_tip); /* Create and write the new object id reference */ - cl_git_pass(git_reference_create(&new_reference, g_repo, new_head, &id, 0)); + cl_git_pass(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL, NULL)); /* Ensure the reference can be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head)); @@ -130,7 +130,7 @@ void test_refs_create__oid_unknown(void) git_oid_fromstr(&id, "deadbeef3f795b2b4353bcce3a527ad0a4f7f644"); /* Create and write the new object id reference */ - cl_git_fail(git_reference_create(&new_reference, g_repo, new_head, &id, 0)); + cl_git_fail(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL, NULL)); /* Ensure the reference can't be looked-up... */ cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, new_head)); @@ -144,10 +144,10 @@ void test_refs_create__propagate_eexists(void) /* Make sure it works for oid and for symbolic both */ git_oid_fromstr(&oid, current_master_tip); - error = git_reference_create(&ref, g_repo, current_head_target, &oid, false); + error = git_reference_create(&ref, g_repo, current_head_target, &oid, false, NULL, NULL); cl_assert(error == GIT_EEXISTS); - error = git_reference_symbolic_create(&ref, g_repo, "HEAD", current_head_target, false); + error = git_reference_symbolic_create(&ref, g_repo, "HEAD", current_head_target, false, NULL, NULL); cl_assert(error == GIT_EEXISTS); } @@ -161,8 +161,8 @@ void test_refs_create__creating_a_reference_with_an_invalid_name_returns_EINVALI git_oid_fromstr(&id, current_master_tip); cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_create( - &new_reference, g_repo, name, &id, 0)); + &new_reference, g_repo, name, &id, 0, NULL, NULL)); cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create( - &new_reference, g_repo, name, current_head_target, 0)); + &new_reference, g_repo, name, current_head_target, 0, NULL, NULL)); } diff --git a/tests/refs/createwithlog.c b/tests/refs/createwithlog.c new file mode 100644 index 000000000..026ff6d6a --- /dev/null +++ b/tests/refs/createwithlog.c @@ -0,0 +1,51 @@ +#include "clar_libgit2.h" + +#include "repository.h" +#include "git2/reflog.h" +#include "reflog.h" +#include "ref_helpers.h" + +static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"; + +static git_repository *g_repo; + +void test_refs_createwithlog__initialize(void) +{ + g_repo = cl_git_sandbox_init("testrepo.git"); +} + +void test_refs_createwithlog__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_refs_createwithlog__creating_a_direct_reference_adds_a_reflog_entry(void) +{ + git_reference *reference; + git_oid id; + git_signature *signature; + git_reflog *reflog; + const git_reflog_entry *entry; + + const char *name = "refs/heads/new-head"; + const char *message = "You've been logged, mate!"; + + git_oid_fromstr(&id, current_master_tip); + + cl_git_pass(git_signature_now(&signature, "foo", "foo@bar")); + + cl_git_pass( + git_reference_create(&reference, g_repo, name, &id, 0, signature, message)); + + cl_git_pass(git_reflog_read(&reflog, g_repo, name)); + cl_assert_equal_sz(1, git_reflog_entrycount(reflog)); + + entry = git_reflog_entry_byindex(reflog, 0); + cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0); + cl_assert(git_oid_cmp(&id, &entry->oid_cur) == 0); + cl_assert_equal_s(message, entry->msg); + + git_reflog_free(reflog); + git_reference_free(reference); + git_signature_free(signature); +} diff --git a/tests/refs/delete.c b/tests/refs/delete.c index 973768aeb..9d1c3fd79 100644 --- a/tests/refs/delete.c +++ b/tests/refs/delete.c @@ -66,7 +66,7 @@ void test_refs_delete__packed_only(void) git_oid_fromstr(&id, current_master_tip); /* Create and write the new object id reference */ - cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &id, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &id, 0, NULL, NULL)); git_reference_free(ref); /* Lookup the reference */ @@ -91,3 +91,17 @@ void test_refs_delete__packed_only(void) git_reference_free(ref); git_refdb_free(refdb); } + +void test_refs_delete__remove(void) +{ + git_reference *ref; + + /* Check that passing no old values lets us delete */ + + cl_git_pass(git_reference_lookup(&ref, g_repo, packed_test_head_name)); + git_reference_free(ref); + + cl_git_pass(git_reference_remove(g_repo, packed_test_head_name)); + + cl_git_fail(git_reference_lookup(&ref, g_repo, packed_test_head_name)); +} diff --git a/tests/refs/foreachglob.c b/tests/refs/foreachglob.c index 2c458082f..b992b07b8 100644 --- a/tests/refs/foreachglob.c +++ b/tests/refs/foreachglob.c @@ -12,7 +12,7 @@ void test_refs_foreachglob__initialize(void) cl_git_pass(git_repository_open(&repo, "testrepo.git")); cl_git_pass(git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644")); - cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0)); + cl_git_pass(git_reference_create(&fake_remote, repo, "refs/remotes/nulltoken/master", &id, 0, NULL, NULL)); } void test_refs_foreachglob__cleanup(void) @@ -81,14 +81,14 @@ static int interrupt_cb(const char *reference_name, void *payload) (*count)++; - return (*count == 11); + return (*count == 11) ? -1000 : 0; } void test_refs_foreachglob__can_cancel(void) { int count = 0; - cl_assert_equal_i(GIT_EUSER, git_reference_foreach_glob( + cl_assert_equal_i(-1000, git_reference_foreach_glob( repo, "*", interrupt_cb, &count) ); cl_assert_equal_i(11, count); diff --git a/tests/refs/iterator.c b/tests/refs/iterator.c index 266410fdf..c77451309 100644 --- a/tests/refs/iterator.c +++ b/tests/refs/iterator.c @@ -46,36 +46,43 @@ static int refcmp_cb(const void *a, const void *b) return strcmp(refa->name, refb->name); } +static void assert_all_refnames_match(git_vector *output) +{ + size_t i; + git_reference *ref; + + cl_assert_equal_sz(output->length, ARRAY_SIZE(refnames)); + + git_vector_sort(output); + + git_vector_foreach(output, i, ref) { + cl_assert_equal_s(ref->name, refnames[i]); + git_reference_free(ref); + } + + git_vector_free(output); +} + void test_refs_iterator__list(void) { git_reference_iterator *iter; git_vector output; git_reference *ref; - int error; - size_t i; cl_git_pass(git_vector_init(&output, 32, &refcmp_cb)); cl_git_pass(git_reference_iterator_new(&iter, repo)); - do { - error = git_reference_next(&ref, iter); - cl_assert(error == 0 || error == GIT_ITEROVER); - if (error != GIT_ITEROVER) { - cl_git_pass(git_vector_insert(&output, ref)); - } - } while (!error); + while (1) { + int error = git_reference_next(&ref, iter); + if (error == GIT_ITEROVER) + break; + cl_git_pass(error); + cl_git_pass(git_vector_insert(&output, ref)); + } git_reference_iterator_free(iter); - cl_assert_equal_sz(output.length, ARRAY_SIZE(refnames)); - - git_vector_sort(&output); - - git_vector_foreach(&output, i, ref) { - cl_assert_equal_s(ref->name, refnames[i]); - git_reference_free(ref); - } - git_vector_free(&output); + assert_all_refnames_match(&output); } void test_refs_iterator__empty(void) @@ -95,3 +102,120 @@ void test_refs_iterator__empty(void) git_odb_free(odb); git_repository_free(empty); } + +static int refs_foreach_cb(git_reference *reference, void *payload) +{ + git_vector *output = payload; + cl_git_pass(git_vector_insert(output, reference)); + return 0; +} + +void test_refs_iterator__foreach(void) +{ + git_vector output; + cl_git_pass(git_vector_init(&output, 32, &refcmp_cb)); + cl_git_pass(git_reference_foreach(repo, refs_foreach_cb, &output)); + assert_all_refnames_match(&output); +} + +static int refs_foreach_cancel_cb(git_reference *reference, void *payload) +{ + int *cancel_after = payload; + + git_reference_free(reference); + + if (!*cancel_after) + return -333; + (*cancel_after)--; + return 0; +} + +void test_refs_iterator__foreach_can_cancel(void) +{ + int cancel_after = 3; + cl_git_fail_with( + git_reference_foreach(repo, refs_foreach_cancel_cb, &cancel_after), + -333); + cl_assert_equal_i(0, cancel_after); +} + +static int refs_foreach_name_cb(const char *name, void *payload) +{ + git_vector *output = payload; + cl_git_pass(git_vector_insert(output, git__strdup(name))); + return 0; +} + +void test_refs_iterator__foreach_name(void) +{ + git_vector output; + size_t i; + char *name; + + cl_git_pass(git_vector_init(&output, 32, &git__strcmp_cb)); + cl_git_pass( + git_reference_foreach_name(repo, refs_foreach_name_cb, &output)); + + cl_assert_equal_sz(output.length, ARRAY_SIZE(refnames)); + git_vector_sort(&output); + + git_vector_foreach(&output, i, name) { + cl_assert_equal_s(name, refnames[i]); + git__free(name); + } + + git_vector_free(&output); +} + +static int refs_foreach_name_cancel_cb(const char *name, void *payload) +{ + int *cancel_after = payload; + if (!*cancel_after) + return -333; + GIT_UNUSED(name); + (*cancel_after)--; + return 0; +} + +void test_refs_iterator__foreach_name_can_cancel(void) +{ + int cancel_after = 5; + cl_git_fail_with( + git_reference_foreach_name( + repo, refs_foreach_name_cancel_cb, &cancel_after), + -333); + cl_assert_equal_i(0, cancel_after); +} + +void test_refs_iterator__concurrent_delete(void) +{ + git_reference_iterator *iter; + size_t full_count = 0, concurrent_count = 0; + const char *name; + int error; + + git_repository_free(repo); + repo = cl_git_sandbox_init("testrepo"); + + cl_git_pass(git_reference_iterator_new(&iter, repo)); + while ((error = git_reference_next_name(&name, iter)) == 0) { + full_count++; + } + + git_reference_iterator_free(iter); + cl_assert_equal_i(GIT_ITEROVER, error); + + cl_git_pass(git_reference_iterator_new(&iter, repo)); + while ((error = git_reference_next_name(&name, iter)) == 0) { + cl_git_pass(git_reference_remove(repo, name)); + concurrent_count++; + } + + git_reference_iterator_free(iter); + cl_assert_equal_i(GIT_ITEROVER, error); + + cl_assert_equal_i(full_count, concurrent_count); + + cl_git_sandbox_cleanup(); + repo = NULL; +} diff --git a/tests/refs/overwrite.c b/tests/refs/overwrite.c index ebe72069c..78ce4ace7 100644 --- a/tests/refs/overwrite.c +++ b/tests/refs/overwrite.c @@ -27,8 +27,8 @@ void test_refs_overwrite__symbolic(void) git_reference *ref, *branch_ref; /* The target needds to exist and we need to check the name has changed */ - cl_git_pass(git_reference_symbolic_create(&branch_ref, g_repo, ref_branch_name, ref_master_name, 0)); - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_branch_name, 0)); + cl_git_pass(git_reference_symbolic_create(&branch_ref, g_repo, ref_branch_name, ref_master_name, 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_branch_name, 0, NULL, NULL)); git_reference_free(ref); /* Ensure it points to the right place*/ @@ -38,8 +38,8 @@ void test_refs_overwrite__symbolic(void) git_reference_free(ref); /* Ensure we can't create it unless we force it to */ - cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1)); + cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1, NULL, NULL)); git_reference_free(ref); /* Ensure it points to the right place */ @@ -63,7 +63,7 @@ void test_refs_overwrite__object_id(void) git_reference_free(ref); /* Create it */ - cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL, NULL)); git_reference_free(ref); cl_git_pass(git_reference_lookup(&ref, g_repo, ref_test_name)); @@ -72,8 +72,8 @@ void test_refs_overwrite__object_id(void) git_reference_free(ref); /* Ensure we can't overwrite unless we force it */ - cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0)); - cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1)); + cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL, NULL)); + cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1, NULL, NULL)); git_reference_free(ref); /* Ensure it has been overwritten */ @@ -94,10 +94,10 @@ void test_refs_overwrite__object_id_with_symbolic(void) git_oid_cpy(&id, git_reference_target(ref)); git_reference_free(ref); - cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL, NULL)); git_reference_free(ref); - cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1)); + cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL, NULL)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1, NULL, NULL)); git_reference_free(ref); /* Ensure it points to the right place */ @@ -120,11 +120,11 @@ void test_refs_overwrite__symbolic_with_object_id(void) git_reference_free(ref); /* Create the symbolic ref */ - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL, NULL)); git_reference_free(ref); /* It shouldn't overwrite unless we tell it to */ - cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0)); - cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1)); + cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0, NULL, NULL)); + cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1, NULL, NULL)); git_reference_free(ref); /* Ensure it points to the right place */ diff --git a/tests/refs/pack.c b/tests/refs/pack.c index 849a052aa..7f5c611a7 100644 --- a/tests/refs/pack.c +++ b/tests/refs/pack.c @@ -93,11 +93,11 @@ void test_refs_pack__symbolic(void) for (i = 0; i < 100; ++i) { snprintf(name, sizeof(name), "refs/heads/symbolic-%03d", i); cl_git_pass(git_reference_symbolic_create( - &ref, g_repo, name, "refs/heads/master", 0)); + &ref, g_repo, name, "refs/heads/master", 0, NULL, NULL)); git_reference_free(ref); snprintf(name, sizeof(name), "refs/heads/direct-%03d", i); - cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL, NULL)); git_reference_free(ref); } diff --git a/tests/refs/races.c b/tests/refs/races.c new file mode 100644 index 000000000..643290a8e --- /dev/null +++ b/tests/refs/races.c @@ -0,0 +1,152 @@ +#include "clar_libgit2.h" + +#include "repository.h" +#include "git2/reflog.h" +#include "reflog.h" +#include "ref_helpers.h" + +static const char *commit_id = "099fabac3a9ea935598528c27f866e34089c2eff"; +static const char *refname = "refs/heads/master"; +static const char *other_refname = "refs/heads/foo"; +static const char *other_commit_id = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"; + +static git_repository *g_repo; + +void test_refs_races__initialize(void) +{ + g_repo = cl_git_sandbox_init("testrepo"); +} + +void test_refs_races__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_refs_races__create_matching(void) +{ + git_reference *ref, *ref2, *ref3; + git_oid id, other_id; + + git_oid_fromstr(&id, commit_id); + git_oid_fromstr(&other_id, other_commit_id); + + cl_git_fail_with(GIT_EMODIFIED, git_reference_create_matching(&ref, g_repo, refname, &other_id, 1, &other_id, NULL, NULL)); + + cl_git_pass(git_reference_lookup(&ref, g_repo, refname)); + cl_git_pass(git_reference_create_matching(&ref2, g_repo, refname, &other_id, 1, &id, NULL, NULL)); + cl_git_fail_with(GIT_EMODIFIED, git_reference_set_target(&ref3, ref, &other_id, NULL, NULL)); + + git_reference_free(ref); + git_reference_free(ref2); + git_reference_free(ref3); +} + +void test_refs_races__symbolic_create_matching(void) +{ + git_reference *ref, *ref2, *ref3; + git_oid id, other_id; + + git_oid_fromstr(&id, commit_id); + git_oid_fromstr(&other_id, other_commit_id); + + cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_create_matching(&ref, g_repo, "HEAD", other_refname, 1, other_refname, NULL, NULL)); + + cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); + cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "HEAD", other_refname, 1, NULL, NULL, refname)); + cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_set_target(&ref3, ref, other_refname, NULL, NULL)); + + git_reference_free(ref); + git_reference_free(ref2); + git_reference_free(ref3); +} + +void test_refs_races__delete(void) +{ + git_reference *ref, *ref2; + git_oid id, other_id; + + git_oid_fromstr(&id, commit_id); + git_oid_fromstr(&other_id, other_commit_id); + + /* We can delete a value that matches */ + cl_git_pass(git_reference_lookup(&ref, g_repo, refname)); + cl_git_pass(git_reference_delete(ref)); + git_reference_free(ref); + + /* We cannot delete a symbolic value that doesn't match */ + cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); + cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "HEAD", other_refname, 1, NULL, NULL, refname)); + cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref)); + + git_reference_free(ref); + git_reference_free(ref2); + + cl_git_pass(git_reference_create(&ref, g_repo, refname, &id, 1, NULL, NULL)); + git_reference_free(ref); + + /* We cannot delete an oid value that doesn't match */ + cl_git_pass(git_reference_lookup(&ref, g_repo, refname)); + cl_git_pass(git_reference_create_matching(&ref2, g_repo, refname, &other_id, 1, &id, NULL, NULL)); + cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref)); + + git_reference_free(ref); + git_reference_free(ref2); +} + +void test_refs_races__switch_oid_to_symbolic(void) +{ + git_reference *ref, *ref2, *ref3; + git_oid id, other_id; + + git_oid_fromstr(&id, commit_id); + git_oid_fromstr(&other_id, other_commit_id); + + /* Removing a direct ref when it's currently symbolic should fail */ + cl_git_pass(git_reference_lookup(&ref, g_repo, refname)); + cl_git_pass(git_reference_symbolic_create(&ref2, g_repo, refname, other_refname, 1, NULL, NULL)); + cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref)); + + git_reference_free(ref); + git_reference_free(ref2); + + cl_git_pass(git_reference_create(&ref, g_repo, refname, &id, 1, NULL, NULL)); + git_reference_free(ref); + + /* Updating a direct ref when it's currently symbolic should fail */ + cl_git_pass(git_reference_lookup(&ref, g_repo, refname)); + cl_git_pass(git_reference_symbolic_create(&ref2, g_repo, refname, other_refname, 1, NULL, NULL)); + cl_git_fail_with(GIT_EMODIFIED, git_reference_set_target(&ref3, ref, &other_id, NULL, NULL)); + + git_reference_free(ref); + git_reference_free(ref2); + git_reference_free(ref3); +} + +void test_refs_races__switch_symbolic_to_oid(void) +{ + git_reference *ref, *ref2, *ref3; + git_oid id, other_id; + + git_oid_fromstr(&id, commit_id); + git_oid_fromstr(&other_id, other_commit_id); + + /* Removing a symbolic ref when it's currently direct should fail */ + cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); + cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL, NULL)); + cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref)); + + git_reference_free(ref); + git_reference_free(ref2); + + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, "HEAD", refname, 1, NULL, NULL)); + git_reference_free(ref); + + /* Updating a symbolic ref when it's currently direct should fail */ + cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); + cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL, NULL)); + cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_set_target(&ref3, ref, other_refname, NULL, NULL)); + + git_reference_free(ref); + git_reference_free(ref2); + git_reference_free(ref3); +} diff --git a/tests/refs/read.c b/tests/refs/read.c index 35cf17e9e..52c307eb0 100644 --- a/tests/refs/read.c +++ b/tests/refs/read.c @@ -271,6 +271,21 @@ void test_refs_read__can_determine_if_a_reference_is_a_tag(void) assert_is_tag("refs/remotes/test/master", false); } +static void assert_is_note(const char *name, bool expected_noteness) +{ + git_reference *reference; + cl_git_pass(git_reference_lookup(&reference, g_repo, name)); + cl_assert_equal_i(expected_noteness, git_reference_is_note(reference)); + git_reference_free(reference); +} + +void test_refs_read__can_determine_if_a_reference_is_a_note(void) +{ + assert_is_note("refs/notes/fanout", true); + assert_is_note("refs/heads/packed", false); + assert_is_note("refs/remotes/test/master", false); +} + void test_refs_read__invalid_name_returns_EINVALIDSPEC(void) { git_reference *reference; diff --git a/tests/refs/reflog/reflog.c b/tests/refs/reflog/reflog.c index bcd224270..792b0f05d 100644 --- a/tests/refs/reflog/reflog.c +++ b/tests/refs/reflog/reflog.c @@ -49,17 +49,20 @@ static void assert_appends(const git_signature *committer, const git_oid *oid) /* Read and parse the reflog for this branch */ cl_git_pass(git_reflog_read(&reflog, repo2, new_ref)); - cl_assert_equal_i(2, (int)git_reflog_entrycount(reflog)); + cl_assert_equal_i(3, (int)git_reflog_entrycount(reflog)); + + /* The first one was the creation of the branch */ + entry = git_reflog_entry_byindex(reflog, 2); + cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0); entry = git_reflog_entry_byindex(reflog, 1); assert_signature(committer, entry->committer); - cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0); + cl_assert(git_oid_cmp(oid, &entry->oid_old) == 0); cl_assert(git_oid_cmp(oid, &entry->oid_cur) == 0); cl_assert(entry->msg == NULL); entry = git_reflog_entry_byindex(reflog, 0); assert_signature(committer, entry->committer); - cl_assert(git_oid_cmp(oid, &entry->oid_old) == 0); cl_assert(git_oid_cmp(oid, &entry->oid_cur) == 0); cl_assert_equal_s(commit_msg, entry->msg); @@ -79,7 +82,7 @@ void test_refs_reflog_reflog__append_then_read(void) /* Create a new branch pointing at the HEAD */ git_oid_fromstr(&oid, current_master_tip); - cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &oid, 0)); + cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &oid, 0, NULL, NULL)); git_reference_free(ref); cl_git_pass(git_signature_now(&committer, "foo", "foo@bar")); @@ -97,29 +100,6 @@ void test_refs_reflog_reflog__append_then_read(void) git_signature_free(committer); } -void test_refs_reflog_reflog__append_to_then_read(void) -{ - /* write a reflog for a given reference and ensure it can be read back */ - git_reference *ref; - git_oid oid; - git_signature *committer; - - /* Create a new branch pointing at the HEAD */ - git_oid_fromstr(&oid, current_master_tip); - cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &oid, 0)); - git_reference_free(ref); - - cl_git_pass(git_signature_now(&committer, "foo", "foo@bar")); - - cl_git_fail(git_reflog_append_to(g_repo, new_ref, &oid, committer, "no inner\nnewline")); - cl_git_pass(git_reflog_append_to(g_repo, new_ref, &oid, committer, NULL)); - cl_git_pass(git_reflog_append_to(g_repo, new_ref, &oid, committer, commit_msg "\n")); - - assert_appends(committer, &oid); - - git_signature_free(committer); -} - void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void) { git_reference *master, *new_master; @@ -134,7 +114,7 @@ void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void) cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&moved_log_path))); cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); - cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0)); + cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL, NULL)); git_reference_free(master); cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&master_log_path))); @@ -147,13 +127,7 @@ void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void) static void assert_has_reflog(bool expected_result, const char *name) { - git_reference *ref; - - cl_git_pass(git_reference_lookup(&ref, g_repo, name)); - - cl_assert_equal_i(expected_result, git_reference_has_log(ref)); - - git_reference_free(ref); + cl_assert_equal_i(expected_result, git_reference_has_log(g_repo, name)); } void test_refs_reflog_reflog__reference_has_reflog(void) @@ -191,7 +165,7 @@ void test_refs_reflog_reflog__cannot_write_a_moved_reflog(void) cl_git_pass(git_reflog_write(reflog)); - cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0)); + cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL, NULL)); git_reference_free(master); cl_git_fail(git_reflog_write(reflog)); @@ -207,3 +181,156 @@ void test_refs_reflog_reflog__renaming_with_an_invalid_name_returns_EINVALIDSPEC cl_assert_equal_i(GIT_EINVALIDSPEC, git_reflog_rename(g_repo, "refs/heads/master", "refs/heads/Inv@{id")); } + +void test_refs_reflog_reflog__write_only_std_locations(void) +{ + git_reference *ref; + git_oid id; + + git_oid_fromstr(&id, current_master_tip); + + cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/foo", &id, 1, NULL, NULL)); + git_reference_free(ref); + cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1, NULL, NULL)); + git_reference_free(ref); + cl_git_pass(git_reference_create(&ref, g_repo, "refs/notes/foo", &id, 1, NULL, NULL)); + git_reference_free(ref); + + assert_has_reflog(true, "refs/heads/foo"); + assert_has_reflog(false, "refs/tags/foo"); + assert_has_reflog(true, "refs/notes/foo"); + +} + +void test_refs_reflog_reflog__write_when_explicitly_active(void) +{ + git_reference *ref; + git_oid id; + + git_oid_fromstr(&id, current_master_tip); + git_reference_ensure_log(g_repo, "refs/tags/foo"); + + cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1, NULL, NULL)); + git_reference_free(ref); + assert_has_reflog(true, "refs/tags/foo"); +} + +void test_refs_reflog_reflog__append_to_HEAD_when_changing_current_branch(void) +{ + size_t nlogs, nlogs_after; + git_reference *ref; + git_reflog *log; + git_oid id; + + cl_git_pass(git_reflog_read(&log, g_repo, "HEAD")); + nlogs = git_reflog_entrycount(log); + git_reflog_free(log); + + /* Move it back */ + git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/master", &id, 1, NULL, NULL)); + git_reference_free(ref); + + cl_git_pass(git_reflog_read(&log, g_repo, "HEAD")); + nlogs_after = git_reflog_entrycount(log); + git_reflog_free(log); + + cl_assert_equal_i(nlogs_after, nlogs + 1); +} + +void test_refs_reflog_reflog__do_not_append_when_no_update(void) +{ + size_t nlogs, nlogs_after; + git_reference *ref, *ref2; + git_reflog *log; + + cl_git_pass(git_reflog_read(&log, g_repo, "HEAD")); + nlogs = git_reflog_entrycount(log); + git_reflog_free(log); + + cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/master")); + cl_git_pass(git_reference_create(&ref2, g_repo, "refs/heads/master", + git_reference_target(ref), 1, NULL, NULL)); + + git_reference_free(ref); + git_reference_free(ref2); + + cl_git_pass(git_reflog_read(&log, g_repo, "HEAD")); + nlogs_after = git_reflog_entrycount(log); + git_reflog_free(log); + + cl_assert_equal_i(nlogs_after, nlogs); +} + +static void assert_no_reflog_update(void) +{ + size_t nlogs, nlogs_after; + size_t nlogs_master, nlogs_master_after; + git_reference *ref; + git_reflog *log; + git_oid id; + + cl_git_pass(git_reflog_read(&log, g_repo, "HEAD")); + nlogs = git_reflog_entrycount(log); + git_reflog_free(log); + + cl_git_pass(git_reflog_read(&log, g_repo, "refs/heads/master")); + nlogs_master = git_reflog_entrycount(log); + git_reflog_free(log); + + /* Move it back */ + git_oid_fromstr(&id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/master", &id, 1, NULL, NULL)); + git_reference_free(ref); + + cl_git_pass(git_reflog_read(&log, g_repo, "HEAD")); + nlogs_after = git_reflog_entrycount(log); + git_reflog_free(log); + + cl_assert_equal_i(nlogs_after, nlogs); + + cl_git_pass(git_reflog_read(&log, g_repo, "refs/heads/master")); + nlogs_master_after = git_reflog_entrycount(log); + git_reflog_free(log); + + cl_assert_equal_i(nlogs_after, nlogs); + cl_assert_equal_i(nlogs_master_after, nlogs_master); + +} + +void test_refs_reflog_reflog__logallrefupdates_bare_set_false(void) +{ + git_config *config; + + cl_git_pass(git_repository_config(&config, g_repo)); + cl_git_pass(git_config_set_bool(config, "core.logallrefupdates", false)); + git_config_free(config); + + assert_no_reflog_update(); +} + +void test_refs_reflog_reflog__logallrefupdates_bare_unset(void) +{ + git_config *config; + + cl_git_pass(git_repository_config(&config, g_repo)); + cl_git_pass(git_config_delete_entry(config, "core.logallrefupdates")); + git_config_free(config); + + assert_no_reflog_update(); +} + +void test_refs_reflog_reflog__logallrefupdates_nonbare_set_false(void) +{ + git_config *config; + + cl_git_sandbox_cleanup(); + g_repo = cl_git_sandbox_init("testrepo"); + + + cl_git_pass(git_repository_config(&config, g_repo)); + cl_git_pass(git_config_set_bool(config, "core.logallrefupdates", false)); + git_config_free(config); + + assert_no_reflog_update(); +} diff --git a/tests/refs/rename.c b/tests/refs/rename.c index 543bc4d62..88f0afd9c 100644 --- a/tests/refs/rename.c +++ b/tests/refs/rename.c @@ -49,7 +49,7 @@ void test_refs_rename__loose(void) cl_assert(reference_is_packed(looked_up_ref) == 0); /* Now that the reference is renamed... */ - cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, new_name, 0)); + cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, new_name, 0, NULL, NULL)); cl_assert_equal_s(new_ref->name, new_name); git_reference_free(looked_up_ref); @@ -91,7 +91,7 @@ void test_refs_rename__packed(void) cl_assert(reference_is_packed(looked_up_ref) != 0); /* Now that the reference is renamed... */ - cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, brand_new_name, 0)); + cl_git_pass(git_reference_rename(&new_ref, looked_up_ref, brand_new_name, 0, NULL, NULL)); cl_assert_equal_s(new_ref->name, brand_new_name); git_reference_free(looked_up_ref); @@ -140,7 +140,7 @@ void test_refs_rename__packed_doesnt_pack_others(void) cl_assert(reference_is_packed(looked_up_ref) != 0); /* Now that the reference is renamed... */ - cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, brand_new_name, 0)); + cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, brand_new_name, 0, NULL, NULL)); git_reference_free(looked_up_ref); /* Lookup the other reference */ @@ -166,7 +166,7 @@ void test_refs_rename__name_collision(void) cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name)); /* Can not be renamed to the name of another existing reference. */ - cl_git_fail(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 0)); + cl_git_fail(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 0, NULL, NULL)); git_reference_free(looked_up_ref); /* Failure to rename it hasn't corrupted its state */ @@ -187,12 +187,12 @@ void test_refs_rename__invalid_name(void) /* Can not be renamed with an invalid name. */ cl_assert_equal_i( GIT_EINVALIDSPEC, - git_reference_rename(&renamed_ref, looked_up_ref, "Hello! I'm a very invalid name.", 0)); + git_reference_rename(&renamed_ref, looked_up_ref, "Hello! I'm a very invalid name.", 0, NULL, NULL)); /* Can not be renamed outside of the refs hierarchy * unless it's ALL_CAPS_AND_UNDERSCORES. */ - cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_rename(&renamed_ref, looked_up_ref, "i-will-sudo-you", 0)); + cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_rename(&renamed_ref, looked_up_ref, "i-will-sudo-you", 0, NULL, NULL)); /* Failure to rename it hasn't corrupted its state */ git_reference_free(looked_up_ref); @@ -213,7 +213,7 @@ void test_refs_rename__force_loose_packed(void) git_oid_cpy(&oid, git_reference_target(looked_up_ref)); /* Can be force-renamed to the name of another existing reference. */ - cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 1)); + cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, packed_test_head_name, 1, NULL, NULL)); git_reference_free(looked_up_ref); git_reference_free(renamed_ref); @@ -238,7 +238,7 @@ void test_refs_rename__force_loose(void) git_oid_cpy(&oid, git_reference_target(looked_up_ref)); /* Can be force-renamed to the name of another existing reference. */ - cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, "refs/heads/test", 1)); + cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, "refs/heads/test", 1, NULL, NULL)); git_reference_free(looked_up_ref); git_reference_free(renamed_ref); @@ -268,15 +268,15 @@ void test_refs_rename__overwrite(void) git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ - cl_git_pass(git_reference_create(&ref_one, g_repo, ref_one_name, &id, 0)); - cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0)); + cl_git_pass(git_reference_create(&ref_one, g_repo, ref_one_name, &id, 0, NULL, NULL)); + cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL, NULL)); /* Pack everything */ cl_git_pass(git_repository_refdb(&refdb, g_repo)); cl_git_pass(git_refdb_compress(refdb)); /* Attempt to create illegal reference */ - cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0)); + cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0, NULL, NULL)); /* Illegal reference couldn't be created so this is supposed to fail */ cl_git_fail(git_reference_lookup(&ref_one_new, g_repo, ref_one_name_new)); @@ -301,13 +301,13 @@ void test_refs_rename__prefix(void) git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ - cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0)); + cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL, NULL)); /* An existing reference... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name)); /* Can be rename to a new name starting with the old name. */ - cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name_new, 0)); + cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name_new, 0, NULL, NULL)); git_reference_free(looked_up_ref); git_reference_free(renamed_ref); @@ -334,14 +334,14 @@ void test_refs_rename__move_up(void) git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ - cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0)); + cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0, NULL, NULL)); git_reference_free(ref_two); /* An existing reference... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new)); /* Can be renamed upward the reference tree. */ - cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name, 0)); + cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name, 0, NULL, NULL)); git_reference_free(looked_up_ref); git_reference_free(renamed_ref); @@ -361,7 +361,30 @@ void test_refs_rename__propagate_eexists(void) cl_git_pass(git_reference_lookup(&ref, g_repo, packed_head_name)); - cl_assert_equal_i(GIT_EEXISTS, git_reference_rename(&new_ref, ref, packed_test_head_name, 0)); + cl_assert_equal_i(GIT_EEXISTS, git_reference_rename(&new_ref, ref, packed_test_head_name, 0, NULL, NULL)); git_reference_free(ref); } + +void test_refs_rename__writes_to_reflog(void) +{ + git_reference *ref, *new_ref; + git_reflog *log; + const git_reflog_entry *entry; + git_signature *sig; + + cl_git_pass(git_signature_now(&sig, "me", "foo@example.com")); + + cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name)); + cl_git_pass(git_reference_rename(&new_ref, ref, ref_one_name_new, false, + sig, "message")); + cl_git_pass(git_reflog_read(&log, g_repo, git_reference_name(new_ref))); + entry = git_reflog_entry_byindex(log, 0); + cl_assert_equal_s("message", git_reflog_entry_message(entry)); + cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email); + + git_reflog_free(log); + git_reference_free(ref); + git_reference_free(new_ref); + git_signature_free(sig); +} diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index 37d3981bb..a540f389d 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -325,7 +325,7 @@ static void create_fake_stash_reference_and_reflog(git_repository *repo) cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&log_path))); cl_git_pass(git_reference_lookup(&master, repo, "refs/heads/master")); - cl_git_pass(git_reference_rename(&new_master, master, "refs/fakestash", 0)); + cl_git_pass(git_reference_rename(&new_master, master, "refs/fakestash", 0, NULL, NULL)); git_reference_free(master); cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&log_path))); @@ -596,7 +596,8 @@ void test_refs_revparse__issue_994(void) repo, "refs/remotes/origin/bim_with_3d@11296", git_reference_target(head), - 0)); + 0, + NULL, NULL)); cl_git_pass(git_revparse_single(&target, repo, "origin/bim_with_3d@11296")); git_object_free(target); @@ -633,7 +634,7 @@ void test_refs_revparse__try_to_retrieve_branch_before_described_tag(void) test_object_inrepo("blah-7-gc47800c", "c47800c7266a2be04c571c04d5a6614691ea99bd", repo); cl_git_pass(git_revparse_single(&target, repo, "HEAD~3")); - cl_git_pass(git_branch_create(&branch, repo, "blah-7-gc47800c", (git_commit *)target, 0)); + cl_git_pass(git_branch_create(&branch, repo, "blah-7-gc47800c", (git_commit *)target, 0, NULL, NULL)); git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target)); @@ -671,7 +672,7 @@ void test_refs_revparse__try_to_retrieve_sha_before_branch(void) test_object_inrepo("a65fedf39aefe402d3bb6e24df4d4f5fe4547750", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", repo); cl_git_pass(git_revparse_single(&target, repo, "HEAD~3")); - cl_git_pass(git_branch_create(&branch, repo, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", (git_commit *)target, 0)); + cl_git_pass(git_branch_create(&branch, repo, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", (git_commit *)target, 0, NULL, NULL)); git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target)); @@ -707,7 +708,7 @@ void test_refs_revparse__try_to_retrieve_branch_before_abbrev_sha(void) test_object_inrepo("c47800", "c47800c7266a2be04c571c04d5a6614691ea99bd", repo); cl_git_pass(git_revparse_single(&target, repo, "HEAD~3")); - cl_git_pass(git_branch_create(&branch, repo, "c47800", (git_commit *)target, 0)); + cl_git_pass(git_branch_create(&branch, repo, "c47800", (git_commit *)target, 0, NULL, NULL)); git_oid_tostr(sha, GIT_OID_HEXSZ + 1, git_object_id(target)); diff --git a/tests/refs/settargetwithlog.c b/tests/refs/settargetwithlog.c new file mode 100644 index 000000000..524ce771c --- /dev/null +++ b/tests/refs/settargetwithlog.c @@ -0,0 +1,55 @@ +#include "clar_libgit2.h" + +#include "repository.h" +#include "git2/reflog.h" +#include "reflog.h" +#include "ref_helpers.h" + +static const char *br2_tip = "a4a7dce85cf63874e984719f4fdd239f5145052f"; +static const char *master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"; +static const char *br2_name = "refs/heads/br2"; + +static git_repository *g_repo; + +void test_refs_settargetwithlog__initialize(void) +{ + g_repo = cl_git_sandbox_init("testrepo.git"); +} + +void test_refs_settargetwithlog__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_refs_settargetwithlog__updating_a_direct_reference_adds_a_reflog_entry(void) +{ + git_reference *reference, *reference_out; + git_oid current_id, target_id; + git_signature *signature; + git_reflog *reflog; + const git_reflog_entry *entry; + + const char *message = "You've been logged, mate!"; + + git_oid_fromstr(¤t_id, br2_tip); + git_oid_fromstr(&target_id, master_tip); + + cl_git_pass(git_reference_lookup(&reference, g_repo, br2_name)); + + cl_git_pass(git_signature_now(&signature, "foo", "foo@bar")); + + cl_git_pass(git_reference_set_target( + &reference_out, reference, &target_id, signature, message)); + + cl_git_pass(git_reflog_read(&reflog, g_repo, br2_name)); + + entry = git_reflog_entry_byindex(reflog, 0); + cl_assert(git_oid_cmp(¤t_id, &entry->oid_old) == 0); + cl_assert(git_oid_cmp(&target_id, &entry->oid_cur) == 0); + cl_assert_equal_s(message, entry->msg); + + git_reflog_free(reflog); + git_reference_free(reference_out); + git_reference_free(reference); + git_signature_free(signature); +} diff --git a/tests/refs/setter.c b/tests/refs/setter.c index 6d875f9b6..9a945db00 100644 --- a/tests/refs/setter.c +++ b/tests/refs/setter.c @@ -34,7 +34,7 @@ void test_refs_setter__update_direct(void) cl_git_pass(git_reference_lookup(&test_ref, g_repo, ref_test_name)); cl_assert(git_reference_type(test_ref) == GIT_REF_OID); - cl_git_pass(git_reference_set_target(&new_ref, test_ref, &id)); + cl_git_pass(git_reference_set_target(&new_ref, test_ref, &id, NULL, NULL)); git_reference_free(test_ref); git_reference_free(new_ref); @@ -53,7 +53,7 @@ void test_refs_setter__update_symbolic(void) cl_assert(git_reference_type(head) == GIT_REF_SYMBOLIC); cl_assert(strcmp(git_reference_symbolic_target(head), ref_master_name) == 0); - cl_git_pass(git_reference_symbolic_set_target(&new_head, head, ref_test_name)); + cl_git_pass(git_reference_symbolic_set_target(&new_head, head, ref_test_name, NULL, NULL)); git_reference_free(new_head); git_reference_free(head); @@ -73,7 +73,7 @@ void test_refs_setter__cant_update_direct_with_symbolic(void) cl_assert(git_reference_type(ref) == GIT_REF_OID); git_oid_cpy(&id, git_reference_target(ref)); - cl_git_fail(git_reference_symbolic_set_target(&new, ref, ref_name)); + cl_git_fail(git_reference_symbolic_set_target(&new, ref, ref_name, NULL, NULL)); git_reference_free(ref); } @@ -90,10 +90,10 @@ void test_refs_setter__cant_update_symbolic_with_direct(void) git_reference_free(ref); /* Create the symbolic ref */ - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0, NULL, NULL)); /* Can't set an OID on a direct ref */ - cl_git_fail(git_reference_set_target(&new, ref, &id)); + cl_git_fail(git_reference_set_target(&new, ref, &id, NULL, NULL)); git_reference_free(ref); } diff --git a/tests/refs/unicode.c b/tests/refs/unicode.c index b56012869..471b0b8d3 100644 --- a/tests/refs/unicode.c +++ b/tests/refs/unicode.c @@ -24,7 +24,7 @@ void test_refs_unicode__create_and_lookup(void) /* Create the reference */ cl_git_pass(git_reference_lookup(&ref0, repo, master)); cl_git_pass(git_reference_create( - &ref1, repo, REFNAME, git_reference_target(ref0), 0)); + &ref1, repo, REFNAME, git_reference_target(ref0), 0, NULL, NULL)); cl_assert_equal_s(REFNAME, git_reference_name(ref1)); git_reference_free(ref0); diff --git a/tests/refs/update.c b/tests/refs/update.c index 205b526a2..873fc4ebe 100644 --- a/tests/refs/update.c +++ b/tests/refs/update.c @@ -22,5 +22,5 @@ void test_refs_update__updating_the_target_of_a_symref_with_an_invalid_name_retu cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head)); git_reference_free(head); - cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create(&head, g_repo, GIT_HEAD_FILE, "refs/heads/inv@{id", 1)); + cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create(&head, g_repo, GIT_HEAD_FILE, "refs/heads/inv@{id", 1, NULL, NULL)); } |
