Merge pull request #3128 from libgit2/cmn/push-notify-deleted Add tests for and fix push negotiation notification
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
diff --git a/src/push.c b/src/push.c
index abe90b7..a0d8a05 100644
--- a/src/push.c
+++ b/src/push.c
@@ -529,11 +529,12 @@ static int add_update(git_push *push, push_spec *spec)
u->src_refname = git__strdup(spec->refspec.src);
GITERR_CHECK_ALLOC(u->src_refname);
- u->dst_refname = git__strdup(spec->refspec.src);
+
+ u->dst_refname = git__strdup(spec->refspec.dst);
GITERR_CHECK_ALLOC(u->dst_refname);
- git_oid_cpy(&u->src, &spec->loid);
- git_oid_cpy(&u->dst, &spec->roid);
+ git_oid_cpy(&u->src, &spec->roid);
+ git_oid_cpy(&u->dst, &spec->loid);
return git_vector_insert(&push->updates, u);
}
diff --git a/tests/network/remote/push.c b/tests/network/remote/push.c
new file mode 100644
index 0000000..3486054
--- /dev/null
+++ b/tests/network/remote/push.c
@@ -0,0 +1,114 @@
+#include "clar_libgit2.h"
+#include "git2/sys/commit.h"
+
+static git_remote *_remote;
+static git_repository *_repo, *_dummy;
+
+void test_network_remote_push__initialize(void)
+{
+ cl_fixture_sandbox("testrepo.git");
+ git_repository_open(&_repo, "testrepo.git");
+
+ /* We need a repository to have a remote */
+ cl_git_pass(git_repository_init(&_dummy, "dummy.git", true));
+ cl_git_pass(git_remote_create(&_remote, _dummy, "origin", cl_git_path_url("testrepo.git")));
+}
+
+void test_network_remote_push__cleanup(void)
+{
+ git_remote_free(_remote);
+ _remote = NULL;
+
+ git_repository_free(_repo);
+ _repo = NULL;
+
+ git_repository_free(_dummy);
+ _dummy = NULL;
+
+ cl_fixture_cleanup("testrepo.git");
+ cl_fixture_cleanup("dummy.git");
+}
+
+int negotiation_cb(const git_push_update **updates, size_t len, void *payload)
+{
+ const git_push_update *expected = payload;
+
+ cl_assert_equal_i(1, len);
+ cl_assert_equal_s(expected->src_refname, updates[0]->src_refname);
+ cl_assert_equal_s(expected->dst_refname, updates[0]->dst_refname);
+ cl_assert_equal_oid(&expected->src, &updates[0]->src);
+ cl_assert_equal_oid(&expected->dst, &updates[0]->dst);
+
+ return 0;
+}
+
+void test_network_remote_push__delete_notification(void)
+{
+ git_push_options opts = GIT_PUSH_OPTIONS_INIT;
+ git_reference *ref;
+ git_push_update expected;
+ char *refspec = ":refs/heads/master";
+ const git_strarray refspecs = {
+ &refspec,
+ 1,
+ };
+
+ cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/master"));
+
+ expected.src_refname = "";
+ expected.dst_refname = "refs/heads/master";
+ memset(&expected.dst, 0, sizeof(git_oid));
+ git_oid_cpy(&expected.src, git_reference_target(ref));
+
+ opts.callbacks.push_negotiation = negotiation_cb;
+ opts.callbacks.payload = &expected;
+ cl_git_pass(git_remote_push(_remote, &refspecs, &opts));
+
+ git_reference_free(ref);
+ cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, _repo, "refs/heads/master"));
+
+}
+
+void create_dummy_commit(git_reference **out, git_repository *repo)
+{
+ git_index *index;
+ git_oid tree_id, commit_id;
+ git_signature *sig;
+
+ cl_git_pass(git_repository_index(&index, repo));
+ cl_git_pass(git_index_write_tree(&tree_id, index));
+ git_index_free(index);
+
+ cl_git_pass(git_signature_now(&sig, "Pusher Joe", "pjoe"));
+ cl_git_pass(git_commit_create_from_ids(&commit_id, repo, NULL, sig, sig,
+ NULL, "Empty tree\n", &tree_id, 0, NULL));
+ cl_git_pass(git_reference_create(out, repo, "refs/heads/empty-tree", &commit_id, true, "commit yo"));
+ git_signature_free(sig);
+}
+
+void test_network_remote_push__create_notification(void)
+{
+ git_push_options opts = GIT_PUSH_OPTIONS_INIT;
+ git_reference *ref;
+ git_push_update expected;
+ char *refspec = "refs/heads/empty-tree";
+ const git_strarray refspecs = {
+ &refspec,
+ 1,
+ };
+
+ create_dummy_commit(&ref, _dummy);
+
+ expected.src_refname = "refs/heads/empty-tree";
+ expected.dst_refname = "refs/heads/empty-tree";
+ git_oid_cpy(&expected.dst, git_reference_target(ref));
+ memset(&expected.src, 0, sizeof(git_oid));
+
+ opts.callbacks.push_negotiation = negotiation_cb;
+ opts.callbacks.payload = &expected;
+ cl_git_pass(git_remote_push(_remote, &refspecs, &opts));
+
+ git_reference_free(ref);
+ cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/empty-tree"));
+ git_reference_free(ref);
+}