2 * Copyright (C) the libgit2 contributors. All rights reserved.
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
8 #include "git2/config.h"
9 #include "git2/types.h"
15 #include "repository.h"
20 #include "fetchhead.h"
23 #define CONFIG_URL_FMT "remote.%s.url"
24 #define CONFIG_PUSHURL_FMT "remote.%s.pushurl"
25 #define CONFIG_FETCH_FMT "remote.%s.fetch"
26 #define CONFIG_PUSH_FMT "remote.%s.push"
27 #define CONFIG_TAGOPT_FMT "remote.%s.tagopt"
29 static int dwim_refspecs(git_vector
*out
, git_vector
*refspecs
, git_vector
*refs
);
30 static int lookup_remote_prune_config(git_remote
*remote
, git_config
*config
, const char *name
);
31 char *apply_insteadof(git_config
*config
, const char *url
, int direction
);
33 static int add_refspec_to(git_vector
*vector
, const char *string
, bool is_fetch
)
37 spec
= git__calloc(1, sizeof(git_refspec
));
38 GITERR_CHECK_ALLOC(spec
);
40 if (git_refspec__parse(spec
, string
, is_fetch
) < 0) {
45 spec
->push
= !is_fetch
;
46 if (git_vector_insert(vector
, spec
) < 0) {
47 git_refspec__free(spec
);
55 static int add_refspec(git_remote
*remote
, const char *string
, bool is_fetch
)
57 return add_refspec_to(&remote
->refspecs
, string
, is_fetch
);
60 static int download_tags_value(git_remote
*remote
, git_config
*cfg
)
63 git_buf buf
= GIT_BUF_INIT
;
66 if (git_buf_printf(&buf
, "remote.%s.tagopt", remote
->name
) < 0)
69 error
= git_config__lookup_entry(&ce
, cfg
, git_buf_cstr(&buf
), false);
72 if (!error
&& ce
&& ce
->value
) {
73 if (!strcmp(ce
->value
, "--no-tags"))
74 remote
->download_tags
= GIT_REMOTE_DOWNLOAD_TAGS_NONE
;
75 else if (!strcmp(ce
->value
, "--tags"))
76 remote
->download_tags
= GIT_REMOTE_DOWNLOAD_TAGS_ALL
;
79 git_config_entry_free(ce
);
83 static int ensure_remote_name_is_valid(const char *name
)
87 if (!git_remote_is_valid_name(name
)) {
90 "'%s' is not a valid remote name.", name
? name
: "(null)");
91 error
= GIT_EINVALIDSPEC
;
97 static int write_add_refspec(git_repository
*repo
, const char *name
, const char *refspec
, bool fetch
)
100 git_buf var
= GIT_BUF_INIT
;
105 if ((error
= git_repository_config__weakptr(&cfg
, repo
)) < 0)
108 fmt
= fetch
? CONFIG_FETCH_FMT
: CONFIG_PUSH_FMT
;
110 if ((error
= ensure_remote_name_is_valid(name
)) < 0)
113 if ((error
= git_refspec__parse(&spec
, refspec
, fetch
)) < 0) {
114 if (giterr_last()->klass
!= GITERR_NOMEMORY
)
115 error
= GIT_EINVALIDSPEC
;
120 git_refspec__free(&spec
);
122 if ((error
= git_buf_printf(&var
, fmt
, name
)) < 0)
126 * "$^" is a unmatcheable regexp: it will not match anything at all, so
127 * all values will be considered new and we will not replace any
130 if ((error
= git_config_set_multivar(cfg
, var
.ptr
, "$^", refspec
)) < 0) {
140 /* We could export this as a helper */
141 static int get_check_cert(int *out
, git_repository
*repo
)
149 /* By default, we *DO* want to verify the certificate. */
152 /* Go through the possible sources for SSL verification settings, from
153 * most specific to least specific. */
155 /* GIT_SSL_NO_VERIFY environment variable */
156 if ((val
= p_getenv("GIT_SSL_NO_VERIFY")) != NULL
)
157 return git_config_parse_bool(out
, val
);
159 /* http.sslVerify config setting */
160 if ((error
= git_repository_config__weakptr(&cfg
, repo
)) < 0)
163 *out
= git_config__get_bool_force(cfg
, "http.sslverify", 1);
168 static int canonicalize_url(git_buf
*out
, const char *in
)
170 if (in
== NULL
|| strlen(in
) == 0) {
171 giterr_set(GITERR_INVALID
, "cannot set empty URL");
172 return GIT_EINVALIDSPEC
;
176 /* Given a UNC path like \\server\path, we need to convert this
177 * to //server/path for compatibility with core git.
179 if (in
[0] == '\\' && in
[1] == '\\' &&
180 (git__isalpha(in
[2]) || git__isdigit(in
[2]))) {
182 for (c
= in
; *c
; c
++)
183 git_buf_putc(out
, *c
== '\\' ? '/' : *c
);
185 return git_buf_oom(out
) ? -1 : 0;
189 return git_buf_puts(out
, in
);
192 static int create_internal(git_remote
**out
, git_repository
*repo
, const char *name
, const char *url
, const char *fetch
)
195 git_config
*config
= NULL
;
196 git_buf canonical_url
= GIT_BUF_INIT
;
197 git_buf var
= GIT_BUF_INIT
;
200 /* name is optional */
201 assert(out
&& repo
&& url
);
203 if ((error
= git_repository_config__weakptr(&config
, repo
)) < 0)
206 remote
= git__calloc(1, sizeof(git_remote
));
207 GITERR_CHECK_ALLOC(remote
);
211 if ((error
= git_vector_init(&remote
->refs
, 32, NULL
)) < 0 ||
212 (error
= canonicalize_url(&canonical_url
, url
)) < 0)
215 remote
->url
= apply_insteadof(repo
->_config
, canonical_url
.ptr
, GIT_DIRECTION_FETCH
);
218 remote
->name
= git__strdup(name
);
219 GITERR_CHECK_ALLOC(remote
->name
);
221 if ((error
= git_buf_printf(&var
, CONFIG_URL_FMT
, name
)) < 0)
224 if ((error
= git_config_set_string(config
, var
.ptr
, canonical_url
.ptr
)) < 0)
229 if ((error
= add_refspec(remote
, fetch
, true)) < 0)
232 /* only write for non-anonymous remotes */
233 if (name
&& (error
= write_add_refspec(repo
, name
, fetch
, true)) < 0)
236 if ((error
= git_repository_config_snapshot(&config
, repo
)) < 0)
239 if ((error
= lookup_remote_prune_config(remote
, config
, name
)) < 0)
242 /* Move the data over to where the matching functions can find them */
243 if ((error
= dwim_refspecs(&remote
->active_refspecs
, &remote
->refspecs
, &remote
->refs
)) < 0)
247 /* A remote without a name doesn't download tags */
249 remote
->download_tags
= GIT_REMOTE_DOWNLOAD_TAGS_NONE
;
251 remote
->download_tags
= GIT_REMOTE_DOWNLOAD_TAGS_AUTO
;
261 git_remote_free(remote
);
263 git_config_free(config
);
264 git_buf_free(&canonical_url
);
269 static int ensure_remote_doesnot_exist(git_repository
*repo
, const char *name
)
274 error
= git_remote_lookup(&remote
, repo
, name
);
276 if (error
== GIT_ENOTFOUND
)
282 git_remote_free(remote
);
286 "remote '%s' already exists", name
);
292 int git_remote_create(git_remote
**out
, git_repository
*repo
, const char *name
, const char *url
)
294 git_buf buf
= GIT_BUF_INIT
;
297 if (git_buf_printf(&buf
, "+refs/heads/*:refs/remotes/%s/*", name
) < 0)
300 error
= git_remote_create_with_fetchspec(out
, repo
, name
, url
, git_buf_cstr(&buf
));
306 int git_remote_create_with_fetchspec(git_remote
**out
, git_repository
*repo
, const char *name
, const char *url
, const char *fetch
)
308 git_remote
*remote
= NULL
;
311 if ((error
= ensure_remote_name_is_valid(name
)) < 0)
314 if ((error
= ensure_remote_doesnot_exist(repo
, name
)) < 0)
317 if (create_internal(&remote
, repo
, name
, url
, fetch
) < 0)
325 git_remote_free(remote
);
329 int git_remote_create_anonymous(git_remote
**out
, git_repository
*repo
, const char *url
)
331 return create_internal(out
, repo
, NULL
, url
, NULL
);
334 int git_remote_dup(git_remote
**dest
, git_remote
*source
)
339 git_remote
*remote
= git__calloc(1, sizeof(git_remote
));
340 GITERR_CHECK_ALLOC(remote
);
342 if (source
->name
!= NULL
) {
343 remote
->name
= git__strdup(source
->name
);
344 GITERR_CHECK_ALLOC(remote
->name
);
347 if (source
->url
!= NULL
) {
348 remote
->url
= git__strdup(source
->url
);
349 GITERR_CHECK_ALLOC(remote
->url
);
352 if (source
->pushurl
!= NULL
) {
353 remote
->pushurl
= git__strdup(source
->pushurl
);
354 GITERR_CHECK_ALLOC(remote
->pushurl
);
357 remote
->repo
= source
->repo
;
358 remote
->download_tags
= source
->download_tags
;
359 remote
->prune_refs
= source
->prune_refs
;
361 if (git_vector_init(&remote
->refs
, 32, NULL
) < 0 ||
362 git_vector_init(&remote
->refspecs
, 2, NULL
) < 0 ||
363 git_vector_init(&remote
->active_refspecs
, 2, NULL
) < 0) {
368 git_vector_foreach(&source
->refspecs
, i
, spec
) {
369 if ((error
= add_refspec(remote
, spec
->string
, !spec
->push
)) < 0)
383 struct refspec_cb_data
{
388 static int refspec_cb(const git_config_entry
*entry
, void *payload
)
390 struct refspec_cb_data
*data
= (struct refspec_cb_data
*)payload
;
391 return add_refspec(data
->remote
, entry
->value
, data
->fetch
);
394 static int get_optional_config(
395 bool *found
, git_config
*config
, git_buf
*buf
,
396 git_config_foreach_cb cb
, void *payload
)
399 const char *key
= git_buf_cstr(buf
);
401 if (git_buf_oom(buf
))
405 error
= git_config_get_multivar_foreach(config
, key
, NULL
, cb
, payload
);
407 error
= git_config_get_string(payload
, config
, key
);
412 if (error
== GIT_ENOTFOUND
) {
420 int git_remote_lookup(git_remote
**out
, git_repository
*repo
, const char *name
)
423 git_buf buf
= GIT_BUF_INIT
;
427 struct refspec_cb_data data
= { NULL
};
428 bool optional_setting_found
= false, found
;
430 assert(out
&& repo
&& name
);
432 if ((error
= ensure_remote_name_is_valid(name
)) < 0)
435 if ((error
= git_repository_config_snapshot(&config
, repo
)) < 0)
438 remote
= git__calloc(1, sizeof(git_remote
));
439 GITERR_CHECK_ALLOC(remote
);
441 remote
->name
= git__strdup(name
);
442 GITERR_CHECK_ALLOC(remote
->name
);
444 if (git_vector_init(&remote
->refs
, 32, NULL
) < 0 ||
445 git_vector_init(&remote
->refspecs
, 2, NULL
) < 0 ||
446 git_vector_init(&remote
->passive_refspecs
, 2, NULL
) < 0 ||
447 git_vector_init(&remote
->active_refspecs
, 2, NULL
) < 0) {
452 if ((error
= git_buf_printf(&buf
, "remote.%s.url", name
)) < 0)
455 if ((error
= get_optional_config(&found
, config
, &buf
, NULL
, (void *)&val
)) < 0)
458 optional_setting_found
|= found
;
461 remote
->download_tags
= GIT_REMOTE_DOWNLOAD_TAGS_AUTO
;
463 if (found
&& strlen(val
) > 0) {
464 remote
->url
= apply_insteadof(config
, val
, GIT_DIRECTION_FETCH
);
465 GITERR_CHECK_ALLOC(remote
->url
);
470 git_buf_printf(&buf
, "remote.%s.pushurl", name
);
472 if ((error
= get_optional_config(&found
, config
, &buf
, NULL
, (void *)&val
)) < 0)
475 optional_setting_found
|= found
;
477 if (!optional_setting_found
) {
478 error
= GIT_ENOTFOUND
;
479 giterr_set(GITERR_CONFIG
, "remote '%s' does not exist", name
);
483 if (found
&& strlen(val
) > 0) {
484 remote
->pushurl
= apply_insteadof(config
, val
, GIT_DIRECTION_PUSH
);
485 GITERR_CHECK_ALLOC(remote
->pushurl
);
488 data
.remote
= remote
;
492 git_buf_printf(&buf
, "remote.%s.fetch", name
);
494 if ((error
= get_optional_config(NULL
, config
, &buf
, refspec_cb
, &data
)) < 0)
499 git_buf_printf(&buf
, "remote.%s.push", name
);
501 if ((error
= get_optional_config(NULL
, config
, &buf
, refspec_cb
, &data
)) < 0)
504 if (download_tags_value(remote
, config
) < 0)
507 if ((error
= lookup_remote_prune_config(remote
, config
, name
)) < 0)
510 /* Move the data over to where the matching functions can find them */
511 if ((error
= dwim_refspecs(&remote
->active_refspecs
, &remote
->refspecs
, &remote
->refs
)) < 0)
517 git_config_free(config
);
521 git_remote_free(remote
);
526 static int lookup_remote_prune_config(git_remote
*remote
, git_config
*config
, const char *name
)
528 git_buf buf
= GIT_BUF_INIT
;
531 git_buf_printf(&buf
, "remote.%s.prune", name
);
533 if ((error
= git_config_get_bool(&remote
->prune_refs
, config
, git_buf_cstr(&buf
))) < 0) {
534 if (error
== GIT_ENOTFOUND
) {
537 if ((error
= git_config_get_bool(&remote
->prune_refs
, config
, "fetch.prune")) < 0) {
538 if (error
== GIT_ENOTFOUND
) {
550 const char *git_remote_name(const git_remote
*remote
)
556 git_repository
*git_remote_owner(const git_remote
*remote
)
562 const char *git_remote_url(const git_remote
*remote
)
568 static int set_url(git_repository
*repo
, const char *remote
, const char *pattern
, const char *url
)
571 git_buf buf
= GIT_BUF_INIT
, canonical_url
= GIT_BUF_INIT
;
574 assert(repo
&& remote
);
576 if ((error
= ensure_remote_name_is_valid(remote
)) < 0)
579 if ((error
= git_repository_config__weakptr(&cfg
, repo
)) < 0)
582 if ((error
= git_buf_printf(&buf
, pattern
, remote
)) < 0)
586 if ((error
= canonicalize_url(&canonical_url
, url
)) < 0)
589 error
= git_config_set_string(cfg
, buf
.ptr
, url
);
591 error
= git_config_delete_entry(cfg
, buf
.ptr
);
595 git_buf_free(&canonical_url
);
601 int git_remote_set_url(git_repository
*repo
, const char *remote
, const char *url
)
603 return set_url(repo
, remote
, CONFIG_URL_FMT
, url
);
606 const char *git_remote_pushurl(const git_remote
*remote
)
609 return remote
->pushurl
;
612 int git_remote_set_pushurl(git_repository
*repo
, const char *remote
, const char* url
)
614 return set_url(repo
, remote
, CONFIG_PUSHURL_FMT
, url
);
617 const char* git_remote__urlfordirection(git_remote
*remote
, int direction
)
621 assert(direction
== GIT_DIRECTION_FETCH
|| direction
== GIT_DIRECTION_PUSH
);
623 if (direction
== GIT_DIRECTION_FETCH
) {
627 if (direction
== GIT_DIRECTION_PUSH
) {
628 return remote
->pushurl
? remote
->pushurl
: remote
->url
;
634 int set_transport_callbacks(git_transport
*t
, const git_remote_callbacks
*cbs
)
636 if (!t
->set_callbacks
|| !cbs
)
639 return t
->set_callbacks(t
, cbs
->sideband_progress
, NULL
,
640 cbs
->certificate_check
, cbs
->payload
);
643 static int set_transport_custom_headers(git_transport
*t
, const git_strarray
*custom_headers
)
645 if (!t
->set_custom_headers
)
648 return t
->set_custom_headers(t
, custom_headers
);
651 int git_remote_connect(git_remote
*remote
, git_direction direction
, const git_remote_callbacks
*callbacks
, const git_proxy_options
*proxy
, const git_strarray
*custom_headers
)
655 int flags
= GIT_TRANSPORTFLAGS_NONE
;
657 void *payload
= NULL
;
658 git_cred_acquire_cb credentials
= NULL
;
659 git_transport_cb transport
= NULL
;
664 GITERR_CHECK_VERSION(callbacks
, GIT_REMOTE_CALLBACKS_VERSION
, "git_remote_callbacks");
665 credentials
= callbacks
->credentials
;
666 transport
= callbacks
->transport
;
667 payload
= callbacks
->payload
;
671 GITERR_CHECK_VERSION(proxy
, GIT_PROXY_OPTIONS_VERSION
, "git_proxy_options");
673 t
= remote
->transport
;
675 url
= git_remote__urlfordirection(remote
, direction
);
677 giterr_set(GITERR_INVALID
,
678 "Malformed remote '%s' - missing URL", remote
->name
);
682 /* If we don't have a transport object yet, and the caller specified a
683 * custom transport factory, use that */
684 if (!t
&& transport
&&
685 (error
= transport(&t
, remote
, payload
)) < 0)
688 /* If we still don't have a transport, then use the global
689 * transport registrations which map URI schemes to transport factories */
690 if (!t
&& (error
= git_transport_new(&t
, remote
, url
)) < 0)
693 if ((error
= set_transport_custom_headers(t
, custom_headers
)) != 0)
696 if ((error
= set_transport_callbacks(t
, callbacks
)) < 0 ||
697 (error
= t
->connect(t
, url
, credentials
, payload
, proxy
, direction
, flags
)) != 0)
700 remote
->transport
= t
;
707 if (t
== remote
->transport
)
708 remote
->transport
= NULL
;
713 int git_remote_ls(const git_remote_head
***out
, size_t *size
, git_remote
*remote
)
717 if (!remote
->transport
) {
718 giterr_set(GITERR_NET
, "this remote has never connected");
722 return remote
->transport
->ls(out
, size
, remote
->transport
);
725 int git_remote__get_http_proxy(git_remote
*remote
, bool use_ssl
, char **proxy_url
)
728 git_config_entry
*ce
= NULL
;
729 git_buf val
= GIT_BUF_INIT
;
734 if (!proxy_url
|| !remote
->repo
)
739 if ((error
= git_repository_config__weakptr(&cfg
, remote
->repo
)) < 0)
742 /* Go through the possible sources for proxy configuration, from most specific
743 * to least specific. */
745 /* remote.<name>.proxy config setting */
746 if (remote
->name
&& remote
->name
[0]) {
747 git_buf buf
= GIT_BUF_INIT
;
749 if ((error
= git_buf_printf(&buf
, "remote.%s.proxy", remote
->name
)) < 0)
752 error
= git_config__lookup_entry(&ce
, cfg
, git_buf_cstr(&buf
), false);
758 if (ce
&& ce
->value
) {
759 *proxy_url
= git__strdup(ce
->value
);
764 /* http.proxy config setting */
765 if ((error
= git_config__lookup_entry(&ce
, cfg
, "http.proxy", false)) < 0)
768 if (ce
&& ce
->value
) {
769 *proxy_url
= git__strdup(ce
->value
);
773 /* http_proxy / https_proxy environment variables */
774 error
= git__getenv(&val
, use_ssl
? "https_proxy" : "http_proxy");
776 /* try uppercase environment variables */
777 if (error
== GIT_ENOTFOUND
)
778 error
= git__getenv(&val
, use_ssl
? "HTTPS_PROXY" : "HTTP_PROXY");
781 if (error
== GIT_ENOTFOUND
) {
789 *proxy_url
= git_buf_detach(&val
);
792 GITERR_CHECK_ALLOC(*proxy_url
);
793 git_config_entry_free(ce
);
798 /* DWIM `refspecs` based on `refs` and append the output to `out` */
799 static int dwim_refspecs(git_vector
*out
, git_vector
*refspecs
, git_vector
*refs
)
804 git_vector_foreach(refspecs
, i
, spec
) {
805 if (git_refspec__dwim_one(out
, spec
, refs
) < 0)
812 static void free_refspecs(git_vector
*vec
)
817 git_vector_foreach(vec
, i
, spec
) {
818 git_refspec__free(spec
);
822 git_vector_clear(vec
);
825 static int remote_head_cmp(const void *_a
, const void *_b
)
827 const git_remote_head
*a
= (git_remote_head
*) _a
;
828 const git_remote_head
*b
= (git_remote_head
*) _b
;
830 return git__strcmp_cb(a
->name
, b
->name
);
833 static int ls_to_vector(git_vector
*out
, git_remote
*remote
)
835 git_remote_head
**heads
;
838 if (git_remote_ls((const git_remote_head
***)&heads
, &heads_len
, remote
) < 0)
841 if (git_vector_init(out
, heads_len
, remote_head_cmp
) < 0)
844 for (i
= 0; i
< heads_len
; i
++) {
845 if (git_vector_insert(out
, heads
[i
]) < 0)
852 int git_remote_download(git_remote
*remote
, const git_strarray
*refspecs
, const git_fetch_options
*opts
)
856 git_vector
*to_active
, specs
= GIT_VECTOR_INIT
, refs
= GIT_VECTOR_INIT
;
857 const git_remote_callbacks
*cbs
= NULL
;
858 const git_strarray
*custom_headers
= NULL
;
859 const git_proxy_options
*proxy
= NULL
;
864 GITERR_CHECK_VERSION(&opts
->callbacks
, GIT_REMOTE_CALLBACKS_VERSION
, "git_remote_callbacks");
865 cbs
= &opts
->callbacks
;
866 custom_headers
= &opts
->custom_headers
;
867 GITERR_CHECK_VERSION(&opts
->proxy_opts
, GIT_PROXY_OPTIONS_VERSION
, "git_proxy_options");
868 proxy
= &opts
->proxy_opts
;
871 if (!git_remote_connected(remote
) &&
872 (error
= git_remote_connect(remote
, GIT_DIRECTION_FETCH
, cbs
, proxy
, custom_headers
)) < 0)
875 if (ls_to_vector(&refs
, remote
) < 0)
878 if ((git_vector_init(&specs
, 0, NULL
)) < 0)
881 remote
->passed_refspecs
= 0;
882 if (!refspecs
|| !refspecs
->count
) {
883 to_active
= &remote
->refspecs
;
885 for (i
= 0; i
< refspecs
->count
; i
++) {
886 if ((error
= add_refspec_to(&specs
, refspecs
->strings
[i
], true)) < 0)
891 remote
->passed_refspecs
= 1;
894 free_refspecs(&remote
->passive_refspecs
);
895 if ((error
= dwim_refspecs(&remote
->passive_refspecs
, &remote
->refspecs
, &refs
)) < 0)
898 free_refspecs(&remote
->active_refspecs
);
899 error
= dwim_refspecs(&remote
->active_refspecs
, to_active
, &refs
);
901 git_vector_free(&refs
);
902 free_refspecs(&specs
);
903 git_vector_free(&specs
);
909 git_push_free(remote
->push
);
913 if ((error
= git_fetch_negotiate(remote
, opts
)) < 0)
916 return git_fetch_download_pack(remote
, cbs
);
919 git_vector_free(&refs
);
920 free_refspecs(&specs
);
921 git_vector_free(&specs
);
925 int git_remote_fetch(
927 const git_strarray
*refspecs
,
928 const git_fetch_options
*opts
,
929 const char *reflog_message
)
931 int error
, update_fetchhead
= 1;
932 git_remote_autotag_option_t tagopt
= remote
->download_tags
;
934 git_buf reflog_msg_buf
= GIT_BUF_INIT
;
935 const git_remote_callbacks
*cbs
= NULL
;
936 const git_strarray
*custom_headers
= NULL
;
937 const git_proxy_options
*proxy
= NULL
;
940 GITERR_CHECK_VERSION(&opts
->callbacks
, GIT_REMOTE_CALLBACKS_VERSION
, "git_remote_callbacks");
941 cbs
= &opts
->callbacks
;
942 custom_headers
= &opts
->custom_headers
;
943 update_fetchhead
= opts
->update_fetchhead
;
944 tagopt
= opts
->download_tags
;
945 GITERR_CHECK_VERSION(&opts
->proxy_opts
, GIT_PROXY_OPTIONS_VERSION
, "git_proxy_options");
946 proxy
= &opts
->proxy_opts
;
949 /* Connect and download everything */
950 if ((error
= git_remote_connect(remote
, GIT_DIRECTION_FETCH
, cbs
, proxy
, custom_headers
)) != 0)
953 error
= git_remote_download(remote
, refspecs
, opts
);
955 /* We don't need to be connected anymore */
956 git_remote_disconnect(remote
);
958 /* If the download failed, return the error */
962 /* Default reflog message */
964 git_buf_sets(&reflog_msg_buf
, reflog_message
);
966 git_buf_printf(&reflog_msg_buf
, "fetch %s",
967 remote
->name
? remote
->name
: remote
->url
);
970 /* Create "remote/foo" branches for all remote branches */
971 error
= git_remote_update_tips(remote
, cbs
, update_fetchhead
, tagopt
, git_buf_cstr(&reflog_msg_buf
));
972 git_buf_free(&reflog_msg_buf
);
976 if (opts
&& opts
->prune
== GIT_FETCH_PRUNE
)
978 else if (opts
&& opts
->prune
== GIT_FETCH_PRUNE_UNSPECIFIED
&& remote
->prune_refs
)
980 else if (opts
&& opts
->prune
== GIT_FETCH_NO_PRUNE
)
983 prune
= remote
->prune_refs
;
986 error
= git_remote_prune(remote
, cbs
);
991 static int remote_head_for_fetchspec_src(git_remote_head
**out
, git_vector
*update_heads
, const char *fetchspec_src
)
994 git_remote_head
*remote_ref
;
996 assert(update_heads
&& fetchspec_src
);
1000 git_vector_foreach(update_heads
, i
, remote_ref
) {
1001 if (strcmp(remote_ref
->name
, fetchspec_src
) == 0) {
1010 static int ref_to_update(int *update
, git_buf
*remote_name
, git_remote
*remote
, git_refspec
*spec
, const char *ref_name
)
1013 git_repository
*repo
;
1014 git_buf upstream_remote
= GIT_BUF_INIT
;
1015 git_buf upstream_name
= GIT_BUF_INIT
;
1017 repo
= git_remote_owner(remote
);
1019 if ((!git_reference__is_branch(ref_name
)) ||
1020 !git_remote_name(remote
) ||
1021 (error
= git_branch_upstream_remote(&upstream_remote
, repo
, ref_name
) < 0) ||
1022 git__strcmp(git_remote_name(remote
), git_buf_cstr(&upstream_remote
)) ||
1023 (error
= git_branch_upstream_name(&upstream_name
, repo
, ref_name
)) < 0 ||
1024 !git_refspec_dst_matches(spec
, git_buf_cstr(&upstream_name
)) ||
1025 (error
= git_refspec_rtransform(remote_name
, spec
, upstream_name
.ptr
)) < 0) {
1026 /* Not an error if there is no upstream */
1027 if (error
== GIT_ENOTFOUND
) {
1037 git_buf_free(&upstream_remote
);
1038 git_buf_free(&upstream_name
);
1042 static int remote_head_for_ref(git_remote_head
**out
, git_remote
*remote
, git_refspec
*spec
, git_vector
*update_heads
, git_reference
*ref
)
1044 git_reference
*resolved_ref
= NULL
;
1045 git_buf remote_name
= GIT_BUF_INIT
;
1046 git_config
*config
= NULL
;
1047 const char *ref_name
;
1048 int error
= 0, update
;
1050 assert(out
&& spec
&& ref
);
1054 error
= git_reference_resolve(&resolved_ref
, ref
);
1056 /* If we're in an unborn branch, let's pretend nothing happened */
1057 if (error
== GIT_ENOTFOUND
&& git_reference_type(ref
) == GIT_REF_SYMBOLIC
) {
1058 ref_name
= git_reference_symbolic_target(ref
);
1061 ref_name
= git_reference_name(resolved_ref
);
1064 if ((error
= ref_to_update(&update
, &remote_name
, remote
, spec
, ref_name
)) < 0)
1068 error
= remote_head_for_fetchspec_src(out
, update_heads
, git_buf_cstr(&remote_name
));
1071 git_buf_free(&remote_name
);
1072 git_reference_free(resolved_ref
);
1073 git_config_free(config
);
1077 static int git_remote_write_fetchhead(git_remote
*remote
, git_refspec
*spec
, git_vector
*update_heads
)
1079 git_reference
*head_ref
= NULL
;
1080 git_fetchhead_ref
*fetchhead_ref
;
1081 git_remote_head
*remote_ref
, *merge_remote_ref
;
1082 git_vector fetchhead_refs
;
1083 bool include_all_fetchheads
;
1089 /* no heads, nothing to do */
1090 if (update_heads
->length
== 0)
1093 if (git_vector_init(&fetchhead_refs
, update_heads
->length
, git_fetchhead_ref_cmp
) < 0)
1096 /* Iff refspec is * (but not subdir slash star), include tags */
1097 include_all_fetchheads
= (strcmp(GIT_REFS_HEADS_DIR
"*", git_refspec_src(spec
)) == 0);
1099 /* Determine what to merge: if refspec was a wildcard, just use HEAD */
1100 if (git_refspec_is_wildcard(spec
)) {
1101 if ((error
= git_reference_lookup(&head_ref
, remote
->repo
, GIT_HEAD_FILE
)) < 0 ||
1102 (error
= remote_head_for_ref(&merge_remote_ref
, remote
, spec
, update_heads
, head_ref
)) < 0)
1105 /* If we're fetching a single refspec, that's the only thing that should be in FETCH_HEAD. */
1106 if ((error
= remote_head_for_fetchspec_src(&merge_remote_ref
, update_heads
, git_refspec_src(spec
))) < 0)
1110 /* Create the FETCH_HEAD file */
1111 git_vector_foreach(update_heads
, i
, remote_ref
) {
1112 int merge_this_fetchhead
= (merge_remote_ref
== remote_ref
);
1114 if (!include_all_fetchheads
&&
1115 !git_refspec_src_matches(spec
, remote_ref
->name
) &&
1116 !merge_this_fetchhead
)
1119 if (git_fetchhead_ref_create(&fetchhead_ref
,
1121 merge_this_fetchhead
,
1123 git_remote_url(remote
)) < 0)
1126 if (git_vector_insert(&fetchhead_refs
, fetchhead_ref
) < 0)
1130 git_fetchhead_write(remote
->repo
, &fetchhead_refs
);
1133 for (i
= 0; i
< fetchhead_refs
.length
; ++i
)
1134 git_fetchhead_ref_free(fetchhead_refs
.contents
[i
]);
1136 git_vector_free(&fetchhead_refs
);
1137 git_reference_free(head_ref
);
1143 * Generate a list of candidates for pruning by getting a list of
1144 * references which match the rhs of an active refspec.
1146 static int prune_candidates(git_vector
*candidates
, git_remote
*remote
)
1148 git_strarray arr
= { 0 };
1152 if ((error
= git_reference_list(&arr
, remote
->repo
)) < 0)
1155 for (i
= 0; i
< arr
.count
; i
++) {
1156 const char *refname
= arr
.strings
[i
];
1159 if (!git_remote__matching_dst_refspec(remote
, refname
))
1162 refname_dup
= git__strdup(refname
);
1163 GITERR_CHECK_ALLOC(refname_dup
);
1165 if ((error
= git_vector_insert(candidates
, refname_dup
)) < 0)
1170 git_strarray_free(&arr
);
1174 static int find_head(const void *_a
, const void *_b
)
1176 git_remote_head
*a
= (git_remote_head
*) _a
;
1177 git_remote_head
*b
= (git_remote_head
*) _b
;
1179 return strcmp(a
->name
, b
->name
);
1182 int git_remote_prune(git_remote
*remote
, const git_remote_callbacks
*callbacks
)
1185 git_vector remote_refs
= GIT_VECTOR_INIT
;
1186 git_vector candidates
= GIT_VECTOR_INIT
;
1187 const git_refspec
*spec
;
1188 const char *refname
;
1190 git_oid zero_id
= {{ 0 }};
1193 GITERR_CHECK_VERSION(callbacks
, GIT_REMOTE_CALLBACKS_VERSION
, "git_remote_callbacks");
1195 if ((error
= ls_to_vector(&remote_refs
, remote
)) < 0)
1198 git_vector_set_cmp(&remote_refs
, find_head
);
1200 if ((error
= prune_candidates(&candidates
, remote
)) < 0)
1204 * Remove those entries from the candidate list for which we
1205 * can find a remote reference in at least one refspec.
1207 git_vector_foreach(&candidates
, i
, refname
) {
1208 git_vector_foreach(&remote
->active_refspecs
, j
, spec
) {
1209 git_buf buf
= GIT_BUF_INIT
;
1212 git_remote_head key
= {0};
1214 if (!git_refspec_dst_matches(spec
, refname
))
1217 if ((error
= git_refspec_rtransform(&buf
, spec
, refname
)) < 0)
1220 key
.name
= (char *) git_buf_cstr(&buf
);
1221 error
= git_vector_search(&pos
, &remote_refs
, &key
);
1224 if (error
< 0 && error
!= GIT_ENOTFOUND
)
1227 if (error
== GIT_ENOTFOUND
)
1230 /* if we did find a source, remove it from the candiates */
1231 if ((error
= git_vector_set((void **) &src_name
, &candidates
, i
, NULL
)) < 0)
1234 git__free(src_name
);
1240 * For those candidates still left in the list, we need to
1241 * remove them. We do not remove symrefs, as those are for
1242 * stuff like origin/HEAD which will never match, but we do
1243 * not want to remove them.
1245 git_vector_foreach(&candidates
, i
, refname
) {
1249 if (refname
== NULL
)
1252 error
= git_reference_lookup(&ref
, remote
->repo
, refname
);
1253 /* as we want it gone, let's not consider this an error */
1254 if (error
== GIT_ENOTFOUND
)
1260 if (git_reference_type(ref
) == GIT_REF_SYMBOLIC
) {
1261 git_reference_free(ref
);
1265 git_oid_cpy(&id
, git_reference_target(ref
));
1266 error
= git_reference_delete(ref
);
1267 git_reference_free(ref
);
1271 if (callbacks
&& callbacks
->update_tips
)
1272 error
= callbacks
->update_tips(refname
, &id
, &zero_id
, callbacks
->payload
);
1279 git_vector_free(&remote_refs
);
1280 git_vector_free_deep(&candidates
);
1284 static int update_tips_for_spec(
1286 const git_remote_callbacks
*callbacks
,
1287 int update_fetchhead
,
1288 git_remote_autotag_option_t tagopt
,
1291 const char *log_message
)
1293 int error
= 0, autotag
;
1295 git_buf refname
= GIT_BUF_INIT
;
1298 git_remote_head
*head
;
1300 git_refspec tagspec
;
1301 git_vector update_heads
;
1305 if (git_repository_odb__weakptr(&odb
, remote
->repo
) < 0)
1308 if (git_refspec__parse(&tagspec
, GIT_REFSPEC_TAGS
, true) < 0)
1311 /* Make a copy of the transport's refs */
1312 if (git_vector_init(&update_heads
, 16, NULL
) < 0)
1315 for (; i
< refs
->length
; ++i
) {
1316 head
= git_vector_get(refs
, i
);
1318 git_buf_clear(&refname
);
1320 /* Ignore malformed ref names (which also saves us from tag^{} */
1321 if (!git_reference_is_valid_name(head
->name
))
1324 /* If we have a tag, see if the auto-follow rules say to update it */
1325 if (git_refspec_src_matches(&tagspec
, head
->name
)) {
1326 if (tagopt
!= GIT_REMOTE_DOWNLOAD_TAGS_NONE
) {
1328 if (tagopt
== GIT_REMOTE_DOWNLOAD_TAGS_AUTO
)
1331 git_buf_clear(&refname
);
1332 if (git_buf_puts(&refname
, head
->name
) < 0)
1337 /* If we didn't want to auto-follow the tag, check if the refspec matches */
1338 if (!autotag
&& git_refspec_src_matches(spec
, head
->name
)) {
1340 if (git_refspec_transform(&refname
, spec
, head
->name
) < 0)
1344 * no rhs mans store it in FETCH_HEAD, even if we don't
1345 update anything else.
1347 if ((error
= git_vector_insert(&update_heads
, head
)) < 0)
1354 /* If we still don't have a refname, we don't want it */
1355 if (git_buf_len(&refname
) == 0) {
1359 /* In autotag mode, only create tags for objects already in db */
1360 if (autotag
&& !git_odb_exists(odb
, &head
->oid
))
1363 if (!autotag
&& git_vector_insert(&update_heads
, head
) < 0)
1366 error
= git_reference_name_to_id(&old
, remote
->repo
, refname
.ptr
);
1367 if (error
< 0 && error
!= GIT_ENOTFOUND
)
1370 if (error
== GIT_ENOTFOUND
) {
1371 memset(&old
, 0, GIT_OID_RAWSZ
);
1373 if (autotag
&& git_vector_insert(&update_heads
, head
) < 0)
1377 if (!git_oid__cmp(&old
, &head
->oid
))
1380 /* In autotag mode, don't overwrite any locally-existing tags */
1381 error
= git_reference_create(&ref
, remote
->repo
, refname
.ptr
, &head
->oid
, !autotag
,
1384 if (error
== GIT_EEXISTS
)
1390 git_reference_free(ref
);
1392 if (callbacks
&& callbacks
->update_tips
!= NULL
) {
1393 if (callbacks
->update_tips(refname
.ptr
, &old
, &head
->oid
, callbacks
->payload
) < 0)
1398 if (update_fetchhead
&&
1399 (error
= git_remote_write_fetchhead(remote
, spec
, &update_heads
)) < 0)
1402 git_vector_free(&update_heads
);
1403 git_refspec__free(&tagspec
);
1404 git_buf_free(&refname
);
1408 git_vector_free(&update_heads
);
1409 git_refspec__free(&tagspec
);
1410 git_buf_free(&refname
);
1416 * Iteration over the three vectors, with a pause whenever we find a match
1418 * On each stop, we store the iteration stat in the inout i,j,k
1419 * parameters, and return the currently matching passive refspec as
1420 * well as the head which we matched.
1422 static int next_head(const git_remote
*remote
, git_vector
*refs
,
1423 git_refspec
**out_spec
, git_remote_head
**out_head
,
1424 size_t *out_i
, size_t *out_j
, size_t *out_k
)
1426 const git_vector
*active
, *passive
;
1427 git_remote_head
*head
;
1428 git_refspec
*spec
, *passive_spec
;
1431 active
= &remote
->active_refspecs
;
1432 passive
= &remote
->passive_refspecs
;
1438 for (; i
< refs
->length
; i
++) {
1439 head
= git_vector_get(refs
, i
);
1441 if (!git_reference_is_valid_name(head
->name
))
1444 for (; j
< active
->length
; j
++) {
1445 spec
= git_vector_get(active
, j
);
1447 if (!git_refspec_src_matches(spec
, head
->name
))
1450 for (; k
< passive
->length
; k
++) {
1451 passive_spec
= git_vector_get(passive
, k
);
1453 if (!git_refspec_src_matches(passive_spec
, head
->name
))
1456 *out_spec
= passive_spec
;
1469 return GIT_ITEROVER
;
1472 static int opportunistic_updates(const git_remote
*remote
, const git_remote_callbacks
*callbacks
,
1473 git_vector
*refs
, const char *msg
)
1477 git_remote_head
*head
;
1479 git_buf refname
= GIT_BUF_INIT
;
1484 while ((error
= next_head(remote
, refs
, &spec
, &head
, &i
, &j
, &k
)) == 0) {
1485 git_oid old
= {{ 0 }};
1487 * If we got here, there is a refspec which was used
1488 * for fetching which matches the source of one of the
1489 * passive refspecs, so we should update that
1490 * remote-tracking branch, but not add it to
1494 git_buf_clear(&refname
);
1495 if ((error
= git_refspec_transform(&refname
, spec
, head
->name
)) < 0)
1498 error
= git_reference_name_to_id(&old
, remote
->repo
, refname
.ptr
);
1499 if (error
< 0 && error
!= GIT_ENOTFOUND
)
1502 if (!git_oid_cmp(&old
, &head
->oid
))
1505 /* If we did find a current reference, make sure we haven't lost a race */
1507 error
= git_reference_create(&ref
, remote
->repo
, refname
.ptr
, &head
->oid
, true, msg
);
1509 error
= git_reference_create_matching(&ref
, remote
->repo
, refname
.ptr
, &head
->oid
, true, &old
, msg
);
1510 git_reference_free(ref
);
1514 if (callbacks
&& callbacks
->update_tips
!= NULL
) {
1515 if (callbacks
->update_tips(refname
.ptr
, &old
, &head
->oid
, callbacks
->payload
) < 0)
1520 if (error
== GIT_ITEROVER
)
1524 git_buf_free(&refname
);
1528 int git_remote_update_tips(
1530 const git_remote_callbacks
*callbacks
,
1531 int update_fetchhead
,
1532 git_remote_autotag_option_t download_tags
,
1533 const char *reflog_message
)
1535 git_refspec
*spec
, tagspec
;
1536 git_vector refs
= GIT_VECTOR_INIT
;
1537 git_remote_autotag_option_t tagopt
;
1541 /* push has its own logic hidden away in the push object */
1543 return git_push_update_tips(remote
->push
, callbacks
);
1546 if (git_refspec__parse(&tagspec
, GIT_REFSPEC_TAGS
, true) < 0)
1550 if ((error
= ls_to_vector(&refs
, remote
)) < 0)
1553 if (download_tags
== GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED
)
1554 tagopt
= remote
->download_tags
;
1556 tagopt
= download_tags
;
1558 if (tagopt
== GIT_REMOTE_DOWNLOAD_TAGS_ALL
) {
1559 if ((error
= update_tips_for_spec(remote
, callbacks
, update_fetchhead
, tagopt
, &tagspec
, &refs
, reflog_message
)) < 0)
1563 git_vector_foreach(&remote
->active_refspecs
, i
, spec
) {
1567 if ((error
= update_tips_for_spec(remote
, callbacks
, update_fetchhead
, tagopt
, spec
, &refs
, reflog_message
)) < 0)
1571 /* only try to do opportunisitic updates if the refpec lists differ */
1572 if (remote
->passed_refspecs
)
1573 error
= opportunistic_updates(remote
, callbacks
, &refs
, reflog_message
);
1576 git_vector_free(&refs
);
1577 git_refspec__free(&tagspec
);
1581 int git_remote_connected(const git_remote
*remote
)
1585 if (!remote
->transport
|| !remote
->transport
->is_connected
)
1588 /* Ask the transport if it's connected. */
1589 return remote
->transport
->is_connected(remote
->transport
);
1592 void git_remote_stop(git_remote
*remote
)
1596 if (remote
->transport
&& remote
->transport
->cancel
)
1597 remote
->transport
->cancel(remote
->transport
);
1600 void git_remote_disconnect(git_remote
*remote
)
1604 if (git_remote_connected(remote
))
1605 remote
->transport
->close(remote
->transport
);
1608 void git_remote_free(git_remote
*remote
)
1613 if (remote
->transport
!= NULL
) {
1614 git_remote_disconnect(remote
);
1616 remote
->transport
->free(remote
->transport
);
1617 remote
->transport
= NULL
;
1620 git_vector_free(&remote
->refs
);
1622 free_refspecs(&remote
->refspecs
);
1623 git_vector_free(&remote
->refspecs
);
1625 free_refspecs(&remote
->active_refspecs
);
1626 git_vector_free(&remote
->active_refspecs
);
1628 free_refspecs(&remote
->passive_refspecs
);
1629 git_vector_free(&remote
->passive_refspecs
);
1631 git_push_free(remote
->push
);
1632 git__free(remote
->url
);
1633 git__free(remote
->pushurl
);
1634 git__free(remote
->name
);
1638 static int remote_list_cb(const git_config_entry
*entry
, void *payload
)
1640 git_vector
*list
= payload
;
1641 const char *name
= entry
->name
+ strlen("remote.");
1642 size_t namelen
= strlen(name
);
1645 /* we know name matches "remote.<stuff>.(push)?url" */
1647 if (!strcmp(&name
[namelen
- 4], ".url"))
1648 remote_name
= git__strndup(name
, namelen
- 4); /* strip ".url" */
1650 remote_name
= git__strndup(name
, namelen
- 8); /* strip ".pushurl" */
1651 GITERR_CHECK_ALLOC(remote_name
);
1653 return git_vector_insert(list
, remote_name
);
1656 int git_remote_list(git_strarray
*remotes_list
, git_repository
*repo
)
1660 git_vector list
= GIT_VECTOR_INIT
;
1662 if ((error
= git_repository_config__weakptr(&cfg
, repo
)) < 0)
1665 if ((error
= git_vector_init(&list
, 4, git__strcmp_cb
)) < 0)
1668 error
= git_config_foreach_match(
1669 cfg
, "^remote\\..*\\.(push)?url$", remote_list_cb
, &list
);
1672 git_vector_free_deep(&list
);
1676 git_vector_uniq(&list
, git__free
);
1678 remotes_list
->strings
=
1679 (char **)git_vector_detach(&remotes_list
->count
, NULL
, &list
);
1684 const git_transfer_progress
* git_remote_stats(git_remote
*remote
)
1687 return &remote
->stats
;
1690 git_remote_autotag_option_t
git_remote_autotag(const git_remote
*remote
)
1692 return remote
->download_tags
;
1695 int git_remote_set_autotag(git_repository
*repo
, const char *remote
, git_remote_autotag_option_t value
)
1697 git_buf var
= GIT_BUF_INIT
;
1701 assert(repo
&& remote
);
1703 if ((error
= ensure_remote_name_is_valid(remote
)) < 0)
1706 if ((error
= git_repository_config__weakptr(&config
, repo
)) < 0)
1709 if ((error
= git_buf_printf(&var
, CONFIG_TAGOPT_FMT
, remote
)))
1713 case GIT_REMOTE_DOWNLOAD_TAGS_NONE
:
1714 error
= git_config_set_string(config
, var
.ptr
, "--no-tags");
1716 case GIT_REMOTE_DOWNLOAD_TAGS_ALL
:
1717 error
= git_config_set_string(config
, var
.ptr
, "--tags");
1719 case GIT_REMOTE_DOWNLOAD_TAGS_AUTO
:
1720 error
= git_config_delete_entry(config
, var
.ptr
);
1721 if (error
== GIT_ENOTFOUND
)
1725 giterr_set(GITERR_INVALID
, "invalid value for the tagopt setting");
1733 int git_remote_prune_refs(const git_remote
*remote
)
1735 return remote
->prune_refs
;
1738 static int rename_remote_config_section(
1739 git_repository
*repo
,
1740 const char *old_name
,
1741 const char *new_name
)
1743 git_buf old_section_name
= GIT_BUF_INIT
,
1744 new_section_name
= GIT_BUF_INIT
;
1747 if (git_buf_printf(&old_section_name
, "remote.%s", old_name
) < 0)
1751 (git_buf_printf(&new_section_name
, "remote.%s", new_name
) < 0))
1754 error
= git_config_rename_section(
1756 git_buf_cstr(&old_section_name
),
1757 new_name
? git_buf_cstr(&new_section_name
) : NULL
);
1760 git_buf_free(&old_section_name
);
1761 git_buf_free(&new_section_name
);
1766 struct update_data
{
1768 const char *old_remote_name
;
1769 const char *new_remote_name
;
1772 static int update_config_entries_cb(
1773 const git_config_entry
*entry
,
1776 struct update_data
*data
= (struct update_data
*)payload
;
1778 if (strcmp(entry
->value
, data
->old_remote_name
))
1781 return git_config_set_string(
1782 data
->config
, entry
->name
, data
->new_remote_name
);
1785 static int update_branch_remote_config_entry(
1786 git_repository
*repo
,
1787 const char *old_name
,
1788 const char *new_name
)
1791 struct update_data data
= { NULL
};
1793 if ((error
= git_repository_config__weakptr(&data
.config
, repo
)) < 0)
1796 data
.old_remote_name
= old_name
;
1797 data
.new_remote_name
= new_name
;
1799 return git_config_foreach_match(
1800 data
.config
, "branch\\..+\\.remote", update_config_entries_cb
, &data
);
1803 static int rename_one_remote_reference(
1804 git_reference
*reference_in
,
1805 const char *old_remote_name
,
1806 const char *new_remote_name
)
1809 git_reference
*ref
= NULL
, *dummy
= NULL
;
1810 git_buf
namespace = GIT_BUF_INIT
, old_namespace
= GIT_BUF_INIT
;
1811 git_buf new_name
= GIT_BUF_INIT
;
1812 git_buf log_message
= GIT_BUF_INIT
;
1816 if ((error
= git_buf_printf(&namespace, GIT_REFS_REMOTES_DIR
"%s/", new_remote_name
)) < 0)
1819 pfx_len
= strlen(GIT_REFS_REMOTES_DIR
) + strlen(old_remote_name
) + 1;
1820 git_buf_puts(&new_name
, namespace.ptr
);
1821 if ((error
= git_buf_puts(&new_name
, git_reference_name(reference_in
) + pfx_len
)) < 0)
1824 if ((error
= git_buf_printf(&log_message
,
1825 "renamed remote %s to %s",
1826 old_remote_name
, new_remote_name
)) < 0)
1829 if ((error
= git_reference_rename(&ref
, reference_in
, git_buf_cstr(&new_name
), 1,
1830 git_buf_cstr(&log_message
))) < 0)
1833 if (git_reference_type(ref
) != GIT_REF_SYMBOLIC
)
1836 /* Handle refs like origin/HEAD -> origin/master */
1837 target
= git_reference_symbolic_target(ref
);
1838 if ((error
= git_buf_printf(&old_namespace
, GIT_REFS_REMOTES_DIR
"%s/", old_remote_name
)) < 0)
1841 if (git__prefixcmp(target
, old_namespace
.ptr
))
1844 git_buf_clear(&new_name
);
1845 git_buf_puts(&new_name
, namespace.ptr
);
1846 if ((error
= git_buf_puts(&new_name
, target
+ pfx_len
)) < 0)
1849 error
= git_reference_symbolic_set_target(&dummy
, ref
, git_buf_cstr(&new_name
),
1850 git_buf_cstr(&log_message
));
1852 git_reference_free(dummy
);
1855 git_reference_free(reference_in
);
1856 git_reference_free(ref
);
1857 git_buf_free(&namespace);
1858 git_buf_free(&old_namespace
);
1859 git_buf_free(&new_name
);
1860 git_buf_free(&log_message
);
1864 static int rename_remote_references(
1865 git_repository
*repo
,
1866 const char *old_name
,
1867 const char *new_name
)
1870 git_buf buf
= GIT_BUF_INIT
;
1872 git_reference_iterator
*iter
;
1874 if ((error
= git_buf_printf(&buf
, GIT_REFS_REMOTES_DIR
"%s/*", old_name
)) < 0)
1877 error
= git_reference_iterator_glob_new(&iter
, repo
, git_buf_cstr(&buf
));
1883 while ((error
= git_reference_next(&ref
, iter
)) == 0) {
1884 if ((error
= rename_one_remote_reference(ref
, old_name
, new_name
)) < 0)
1888 git_reference_iterator_free(iter
);
1890 return (error
== GIT_ITEROVER
) ? 0 : error
;
1893 static int rename_fetch_refspecs(git_vector
*problems
, git_remote
*remote
, const char *new_name
)
1896 git_buf base
= GIT_BUF_INIT
, var
= GIT_BUF_INIT
, val
= GIT_BUF_INIT
;
1897 const git_refspec
*spec
;
1901 if ((error
= git_repository_config__weakptr(&config
, remote
->repo
)) < 0)
1904 if ((error
= git_vector_init(problems
, 1, NULL
)) < 0)
1907 if ((error
= git_buf_printf(
1908 &base
, "+refs/heads/*:refs/remotes/%s/*", remote
->name
)) < 0)
1911 git_vector_foreach(&remote
->refspecs
, i
, spec
) {
1915 /* Does the dst part of the refspec follow the expected format? */
1916 if (strcmp(git_buf_cstr(&base
), spec
->string
)) {
1919 dup
= git__strdup(spec
->string
);
1920 GITERR_CHECK_ALLOC(dup
);
1922 if ((error
= git_vector_insert(problems
, dup
)) < 0)
1928 /* If we do want to move it to the new section */
1930 git_buf_clear(&val
);
1931 git_buf_clear(&var
);
1934 &val
, "+refs/heads/*:refs/remotes/%s/*", new_name
) < 0 ||
1935 git_buf_printf(&var
, "remote.%s.fetch", new_name
) < 0)
1941 if ((error
= git_config_set_string(
1942 config
, git_buf_cstr(&var
), git_buf_cstr(&val
))) < 0)
1946 git_buf_free(&base
);
1952 git_vector_foreach(problems
, i
, str
)
1955 git_vector_free(problems
);
1961 int git_remote_rename(git_strarray
*out
, git_repository
*repo
, const char *name
, const char *new_name
)
1964 git_vector problem_refspecs
= GIT_VECTOR_INIT
;
1965 git_remote
*remote
= NULL
;
1967 assert(out
&& repo
&& name
&& new_name
);
1969 if ((error
= git_remote_lookup(&remote
, repo
, name
)) < 0)
1972 if ((error
= ensure_remote_name_is_valid(new_name
)) < 0)
1975 if ((error
= ensure_remote_doesnot_exist(repo
, new_name
)) < 0)
1978 if ((error
= rename_remote_config_section(repo
, name
, new_name
)) < 0)
1981 if ((error
= update_branch_remote_config_entry(repo
, name
, new_name
)) < 0)
1984 if ((error
= rename_remote_references(repo
, name
, new_name
)) < 0)
1987 if ((error
= rename_fetch_refspecs(&problem_refspecs
, remote
, new_name
)) < 0)
1990 out
->count
= problem_refspecs
.length
;
1991 out
->strings
= (char **) problem_refspecs
.contents
;
1995 git_vector_free(&problem_refspecs
);
1997 git_remote_free(remote
);
2001 int git_remote_is_valid_name(
2002 const char *remote_name
)
2004 git_buf buf
= GIT_BUF_INIT
;
2005 git_refspec refspec
;
2008 if (!remote_name
|| *remote_name
== '\0')
2011 git_buf_printf(&buf
, "refs/heads/test:refs/remotes/%s/test", remote_name
);
2012 error
= git_refspec__parse(&refspec
, git_buf_cstr(&buf
), true);
2015 git_refspec__free(&refspec
);
2021 git_refspec
*git_remote__matching_refspec(git_remote
*remote
, const char *refname
)
2026 git_vector_foreach(&remote
->active_refspecs
, i
, spec
) {
2030 if (git_refspec_src_matches(spec
, refname
))
2037 git_refspec
*git_remote__matching_dst_refspec(git_remote
*remote
, const char *refname
)
2042 git_vector_foreach(&remote
->active_refspecs
, i
, spec
) {
2046 if (git_refspec_dst_matches(spec
, refname
))
2053 int git_remote_add_fetch(git_repository
*repo
, const char *remote
, const char *refspec
)
2055 return write_add_refspec(repo
, remote
, refspec
, true);
2058 int git_remote_add_push(git_repository
*repo
, const char *remote
, const char *refspec
)
2060 return write_add_refspec(repo
, remote
, refspec
, false);
2063 static int copy_refspecs(git_strarray
*array
, const git_remote
*remote
, unsigned int push
)
2066 git_vector refspecs
;
2070 if (git_vector_init(&refspecs
, remote
->refspecs
.length
, NULL
) < 0)
2073 git_vector_foreach(&remote
->refspecs
, i
, spec
) {
2074 if (spec
->push
!= push
)
2077 if ((dup
= git__strdup(spec
->string
)) == NULL
)
2080 if (git_vector_insert(&refspecs
, dup
) < 0) {
2086 array
->strings
= (char **)refspecs
.contents
;
2087 array
->count
= refspecs
.length
;
2092 git_vector_free_deep(&refspecs
);
2097 int git_remote_get_fetch_refspecs(git_strarray
*array
, const git_remote
*remote
)
2099 return copy_refspecs(array
, remote
, false);
2102 int git_remote_get_push_refspecs(git_strarray
*array
, const git_remote
*remote
)
2104 return copy_refspecs(array
, remote
, true);
2107 size_t git_remote_refspec_count(const git_remote
*remote
)
2109 return remote
->refspecs
.length
;
2112 const git_refspec
*git_remote_get_refspec(const git_remote
*remote
, size_t n
)
2114 return git_vector_get(&remote
->refspecs
, n
);
2117 int git_remote_init_callbacks(git_remote_callbacks
*opts
, unsigned int version
)
2119 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
2120 opts
, version
, git_remote_callbacks
, GIT_REMOTE_CALLBACKS_INIT
);
2124 /* asserts a branch.<foo>.remote format */
2125 static const char *name_offset(size_t *len_out
, const char *name
)
2130 prefix_len
= strlen("remote.");
2131 dot
= strchr(name
+ prefix_len
, '.');
2135 *len_out
= dot
- name
- prefix_len
;
2136 return name
+ prefix_len
;
2139 static int remove_branch_config_related_entries(
2140 git_repository
*repo
,
2141 const char *remote_name
)
2145 git_config_entry
*entry
;
2146 git_config_iterator
*iter
;
2147 git_buf buf
= GIT_BUF_INIT
;
2149 if ((error
= git_repository_config__weakptr(&config
, repo
)) < 0)
2152 if ((error
= git_config_iterator_glob_new(&iter
, config
, "branch\\..+\\.remote")) < 0)
2155 /* find any branches with us as upstream and remove that config */
2156 while ((error
= git_config_next(&entry
, iter
)) == 0) {
2160 if (strcmp(remote_name
, entry
->value
))
2163 branch
= name_offset(&branch_len
, entry
->name
);
2165 git_buf_clear(&buf
);
2166 if (git_buf_printf(&buf
, "branch.%.*s.merge", (int)branch_len
, branch
) < 0)
2169 if ((error
= git_config_delete_entry(config
, git_buf_cstr(&buf
))) < 0) {
2170 if (error
!= GIT_ENOTFOUND
)
2175 git_buf_clear(&buf
);
2176 if (git_buf_printf(&buf
, "branch.%.*s.remote", (int)branch_len
, branch
) < 0)
2179 if ((error
= git_config_delete_entry(config
, git_buf_cstr(&buf
))) < 0) {
2180 if (error
!= GIT_ENOTFOUND
)
2186 if (error
== GIT_ITEROVER
)
2190 git_config_iterator_free(iter
);
2194 static int remove_refs(git_repository
*repo
, const git_refspec
*spec
)
2196 git_reference_iterator
*iter
= NULL
;
2203 if ((error
= git_vector_init(&refs
, 8, NULL
)) < 0)
2206 if ((error
= git_reference_iterator_new(&iter
, repo
)) < 0)
2209 while ((error
= git_reference_next_name(&name
, iter
)) == 0) {
2210 if (!git_refspec_dst_matches(spec
, name
))
2213 dup
= git__strdup(name
);
2219 if ((error
= git_vector_insert(&refs
, dup
)) < 0)
2222 if (error
== GIT_ITEROVER
)
2227 git_vector_foreach(&refs
, i
, name
) {
2228 if ((error
= git_reference_remove(repo
, name
)) < 0)
2233 git_reference_iterator_free(iter
);
2234 git_vector_foreach(&refs
, i
, dup
) {
2237 git_vector_free(&refs
);
2241 static int remove_remote_tracking(git_repository
*repo
, const char *remote_name
)
2247 /* we want to use what's on the config, regardless of changes to the instance in memory */
2248 if ((error
= git_remote_lookup(&remote
, repo
, remote_name
)) < 0)
2251 count
= git_remote_refspec_count(remote
);
2252 for (i
= 0; i
< count
; i
++) {
2253 const git_refspec
*refspec
= git_remote_get_refspec(remote
, i
);
2255 /* shouldn't ever actually happen */
2256 if (refspec
== NULL
)
2259 if ((error
= remove_refs(repo
, refspec
)) < 0)
2263 git_remote_free(remote
);
2267 int git_remote_delete(git_repository
*repo
, const char *name
)
2271 assert(repo
&& name
);
2273 if ((error
= remove_branch_config_related_entries(repo
, name
)) < 0 ||
2274 (error
= remove_remote_tracking(repo
, name
)) < 0 ||
2275 (error
= rename_remote_config_section(repo
, name
, NULL
)) < 0)
2281 int git_remote_default_branch(git_buf
*out
, git_remote
*remote
)
2283 const git_remote_head
**heads
;
2284 const git_remote_head
*guess
= NULL
;
2285 const git_oid
*head_id
;
2286 size_t heads_len
, i
;
2291 if ((error
= git_remote_ls(&heads
, &heads_len
, remote
)) < 0)
2295 return GIT_ENOTFOUND
;
2297 if (strcmp(heads
[0]->name
, GIT_HEAD_FILE
))
2298 return GIT_ENOTFOUND
;
2300 git_buf_sanitize(out
);
2301 /* the first one must be HEAD so if that has the symref info, we're done */
2302 if (heads
[0]->symref_target
)
2303 return git_buf_puts(out
, heads
[0]->symref_target
);
2306 * If there's no symref information, we have to look over them
2307 * and guess. We return the first match unless the master
2308 * branch is a candidate. Then we return the master branch.
2310 head_id
= &heads
[0]->oid
;
2312 for (i
= 1; i
< heads_len
; i
++) {
2313 if (git_oid_cmp(head_id
, &heads
[i
]->oid
))
2316 if (git__prefixcmp(heads
[i
]->name
, GIT_REFS_HEADS_DIR
))
2324 if (!git__strcmp(GIT_REFS_HEADS_MASTER_FILE
, heads
[i
]->name
)) {
2331 return GIT_ENOTFOUND
;
2333 return git_buf_puts(out
, guess
->name
);
2336 int git_remote_upload(git_remote
*remote
, const git_strarray
*refspecs
, const git_push_options
*opts
)
2342 const git_remote_callbacks
*cbs
= NULL
;
2343 const git_strarray
*custom_headers
= NULL
;
2344 const git_proxy_options
*proxy
= NULL
;
2349 cbs
= &opts
->callbacks
;
2350 custom_headers
= &opts
->custom_headers
;
2351 proxy
= &opts
->proxy_opts
;
2354 if (!git_remote_connected(remote
) &&
2355 (error
= git_remote_connect(remote
, GIT_DIRECTION_PUSH
, cbs
, proxy
, custom_headers
)) < 0)
2358 free_refspecs(&remote
->active_refspecs
);
2359 if ((error
= dwim_refspecs(&remote
->active_refspecs
, &remote
->refspecs
, &remote
->refs
)) < 0)
2363 git_push_free(remote
->push
);
2364 remote
->push
= NULL
;
2367 if ((error
= git_push_new(&remote
->push
, remote
)) < 0)
2370 push
= remote
->push
;
2372 if (opts
&& (error
= git_push_set_options(push
, opts
)) < 0)
2375 if (refspecs
&& refspecs
->count
> 0) {
2376 for (i
= 0; i
< refspecs
->count
; i
++) {
2377 if ((error
= git_push_add_refspec(push
, refspecs
->strings
[i
])) < 0)
2381 git_vector_foreach(&remote
->refspecs
, i
, spec
) {
2384 if ((error
= git_push_add_refspec(push
, spec
->string
)) < 0)
2389 if ((error
= git_push_finish(push
, cbs
)) < 0)
2392 if (cbs
&& cbs
->push_update_reference
&&
2393 (error
= git_push_status_foreach(push
, cbs
->push_update_reference
, cbs
->payload
)) < 0)
2400 int git_remote_push(git_remote
*remote
, const git_strarray
*refspecs
, const git_push_options
*opts
)
2403 const git_remote_callbacks
*cbs
= NULL
;
2404 const git_strarray
*custom_headers
= NULL
;
2405 const git_proxy_options
*proxy
= NULL
;
2408 GITERR_CHECK_VERSION(&opts
->callbacks
, GIT_REMOTE_CALLBACKS_VERSION
, "git_remote_callbacks");
2409 cbs
= &opts
->callbacks
;
2410 custom_headers
= &opts
->custom_headers
;
2411 GITERR_CHECK_VERSION(&opts
->proxy_opts
, GIT_PROXY_OPTIONS_VERSION
, "git_proxy_options");
2412 proxy
= &opts
->proxy_opts
;
2415 assert(remote
&& refspecs
);
2417 if ((error
= git_remote_connect(remote
, GIT_DIRECTION_PUSH
, cbs
, proxy
, custom_headers
)) < 0)
2420 if ((error
= git_remote_upload(remote
, refspecs
, opts
)) < 0)
2423 error
= git_remote_update_tips(remote
, cbs
, 0, 0, NULL
);
2425 git_remote_disconnect(remote
);
2429 #define PREFIX "url"
2430 #define SUFFIX_FETCH "insteadof"
2431 #define SUFFIX_PUSH "pushinsteadof"
2433 char *apply_insteadof(git_config
*config
, const char *url
, int direction
)
2435 size_t match_length
, prefix_length
, suffix_length
;
2436 char *replacement
= NULL
;
2439 git_buf result
= GIT_BUF_INIT
;
2440 git_config_entry
*entry
;
2441 git_config_iterator
*iter
;
2445 assert(direction
== GIT_DIRECTION_FETCH
|| direction
== GIT_DIRECTION_PUSH
);
2447 /* Add 1 to prefix/suffix length due to the additional escaped dot */
2448 prefix_length
= strlen(PREFIX
) + 1;
2449 if (direction
== GIT_DIRECTION_FETCH
) {
2450 regexp
= PREFIX
"\\..*\\." SUFFIX_FETCH
;
2451 suffix_length
= strlen(SUFFIX_FETCH
) + 1;
2453 regexp
= PREFIX
"\\..*\\." SUFFIX_PUSH
;
2454 suffix_length
= strlen(SUFFIX_PUSH
) + 1;
2457 if (git_config_iterator_glob_new(&iter
, config
, regexp
) < 0)
2461 while (git_config_next(&entry
, iter
) == 0) {
2462 size_t n
, replacement_length
;
2464 /* Check if entry value is a prefix of URL */
2465 if (git__prefixcmp(url
, entry
->value
))
2467 /* Check if entry value is longer than previous
2469 if ((n
= strlen(entry
->value
)) <= match_length
)
2472 git__free(replacement
);
2475 /* Cut off prefix and suffix of the value */
2476 replacement_length
=
2477 strlen(entry
->name
) - (prefix_length
+ suffix_length
);
2478 replacement
= git__strndup(entry
->name
+ prefix_length
,
2479 replacement_length
);
2482 git_config_iterator_free(iter
);
2484 if (match_length
== 0)
2485 return git__strdup(url
);
2487 git_buf_printf(&result
, "%s%s", replacement
, url
+ match_length
);
2489 git__free(replacement
);