Skip to content

Commit 72df17c

Browse files
committed
remote: introduce git_remote_ready_cb
Introduce a new callback that fires when the remote is ready to connect.
1 parent 6724067 commit 72df17c

File tree

4 files changed

+72
-4
lines changed

4 files changed

+72
-4
lines changed

include/git2/remote.h

+17
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,18 @@ typedef int GIT_CALLBACK(git_push_update_reference_cb)(const char *refname, cons
513513
*/
514514
typedef int GIT_CALLBACK(git_url_resolve_cb)(git_buf *url_resolved, const char *url, int direction, void *payload);
515515

516+
/**
517+
* Callback invoked immediately before we attempt to connect to the
518+
* given url. Callers may change the URL before the connection by
519+
* calling `git_remote_set_instance_url` in the callback.
520+
*
521+
* @param remote The remote to be connected
522+
* @param direction GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH
523+
* @param payload Payload provided by the caller
524+
* @return 0 on success, or an error
525+
*/
526+
typedef int GIT_CALLBACK(git_remote_ready_cb)(git_remote *remote, int direction, void *payload);
527+
516528
/**
517529
* The callback settings structure
518530
*
@@ -597,6 +609,11 @@ struct git_remote_callbacks {
597609
*/
598610
git_transport_cb transport;
599611

612+
/**
613+
* Callback when the remote is ready to connect.
614+
*/
615+
git_remote_ready_cb remote_ready;
616+
600617
/**
601618
* This will be passed to each of the callbacks in this struct
602619
* as the last parameter.

src/remote.c

+12-3
Original file line numberDiff line numberDiff line change
@@ -709,11 +709,19 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int
709709
GIT_ASSERT_ARG(remote);
710710
GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH);
711711

712-
if (direction == GIT_DIRECTION_FETCH) {
712+
if (callbacks && callbacks->remote_ready) {
713+
int status = callbacks->remote_ready(remote, direction, callbacks->payload);
714+
715+
if (status != 0 && status != GIT_PASSTHROUGH) {
716+
git_error_set_after_callback_function(status, "git_remote_ready_cb");
717+
return status;
718+
}
719+
}
720+
721+
if (direction == GIT_DIRECTION_FETCH)
713722
url = remote->url;
714-
} else if (direction == GIT_DIRECTION_PUSH) {
723+
else if (direction == GIT_DIRECTION_PUSH)
715724
url = remote->pushurl ? remote->pushurl : remote->url;
716-
}
717725

718726
if (!url) {
719727
git_error_set(GIT_ERROR_INVALID,
@@ -722,6 +730,7 @@ int git_remote__urlfordirection(git_buf *url_out, struct git_remote *remote, int
722730
direction == GIT_DIRECTION_FETCH ? "fetch" : "push");
723731
return GIT_EINVALID;
724732
}
733+
725734
return resolve_url(url_out, url, direction, callbacks);
726735
}
727736

tests/network/remote/remotes.c

+42
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,48 @@ void test_network_remote_remotes__parsing(void)
5656
git_buf_dispose(&url);
5757
}
5858

59+
static int remote_ready_callback(git_remote *remote, int direction, void *payload)
60+
{
61+
if (direction == GIT_DIRECTION_PUSH) {
62+
const char *url = git_remote_pushurl(remote);
63+
64+
cl_assert_equal_p(url, NULL);;
65+
cl_assert_equal_s(payload, "payload");
66+
return git_remote_set_instance_pushurl(remote, "push_url");
67+
}
68+
69+
if (direction == GIT_DIRECTION_FETCH) {
70+
const char *url = git_remote_url(remote);
71+
72+
cl_assert_equal_s(url, "git://github.com/libgit2/libgit2");
73+
cl_assert_equal_s(payload, "payload");
74+
return git_remote_set_instance_url(remote, "fetch_url");
75+
}
76+
77+
return -1;
78+
}
79+
80+
void test_network_remote_remotes__remote_ready(void)
81+
{
82+
git_buf url = GIT_BUF_INIT;
83+
84+
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
85+
callbacks.remote_ready = remote_ready_callback;
86+
callbacks.payload = "payload";
87+
88+
cl_assert_equal_s(git_remote_name(_remote), "test");
89+
cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2");
90+
cl_assert(git_remote_pushurl(_remote) == NULL);
91+
92+
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, &callbacks));
93+
cl_assert_equal_s(url.ptr, "fetch_url");
94+
95+
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks));
96+
cl_assert_equal_s(url.ptr, "push_url");
97+
98+
git_buf_dispose(&url);
99+
}
100+
59101
static int urlresolve_callback(git_buf *url_resolved, const char *url, int direction, void *payload)
60102
{
61103
cl_assert(strcmp(url, "git://github.com/libgit2/libgit2") == 0);

tests/online/push_util.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extern const git_oid OID_ZERO;
1212
* @param data pointer to a record_callbacks_data instance
1313
*/
1414
#define RECORD_CALLBACKS_INIT(data) \
15-
{ GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, data, NULL }
15+
{ GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, cred_acquire_cb, NULL, NULL, record_update_tips_cb, NULL, NULL, NULL, NULL, NULL, NULL, data, NULL }
1616

1717
typedef struct {
1818
char *name;

0 commit comments

Comments
 (0)